我在這裏做一個Ruby教程: http://rubymonk.com/learning/books/4-ruby-primer-ascent/chapters/45-more-classes/lessons/105-equality_of_objects比較對象等價於Ruby的
它說當我重載==
運營商,我也應該重載eql?
方法和散列方法,因爲他們是「快」。
但是,如果我用三種方法重載所有這三種方法,其中一個比另一個更快?
我在這裏做一個Ruby教程: http://rubymonk.com/learning/books/4-ruby-primer-ascent/chapters/45-more-classes/lessons/105-equality_of_objects比較對象等價於Ruby的
它說當我重載==
運營商,我也應該重載eql?
方法和散列方法,因爲他們是「快」。
但是,如果我用三種方法重載所有這三種方法,其中一個比另一個更快?
在大多數情況下,==
和eql?
有同樣的結果。在某些情況下,eql?
比==
更嚴格:
42.0 == 42 # => true
42.0.eql?(42) # => false
因此,如果您定義==
你可能要定義eql?
也(反之亦然)。
選擇Hash
類將使用eql?
來區分不同的密鑰,而不是==
。這可能是==
,介意你,但eql?
更乾淨。
爲避免花費大量時間致電eql?
,計算散列值時要求兩個對象eql?
必須具有相同的散列值。該散列值的存儲,這使得未來的查找非常簡單:如果哈希代碼不匹配,則值不eql?
...
出於這個原因,你必須在一個合理的方式定義hash
如果你定義eql?
。
請注意,計算散列值幾乎總是比與==
或eql?
進行比較要貴。但是,一旦散列被計算出來,檢查散列匹配是非常快的。
因爲散列通常涉及非常多的比較,所以對每個鍵執行一次相對昂貴的散列計算,然後對每次查找執行一次。想象一下有10個條目的散列。在第一次查詢完成之前,構建它將涉及到10個對hash
的調用。第一次查找將會相對較快:一次調用hash
,隨後對哈希代碼進行非常有效的比較(實際上比這更快,因爲它們是「索引的」)。如果有一場比賽,我們仍然需要打電話給eql?
以確保這是一場真正的比賽。實際上,兩個不是eql?
的對象可能具有相同的散列。唯一的保證是兩個對象eql?
必須具有相同的散列,但是兩個不同的對象也可以具有相同的散列。
如果您想要使用Array
代替,則每次查找時可能需要10次調用eql?
。
對於什麼是值得的,我不認爲你鏈接到的Ruby引擎是如此清晰。它忽略了這樣一個事實,即計算hash
可能是昂貴的,所以只有當它有意義時,即,當每個元素將被多次比較是一個很好的假設時纔會這樣做。此外,它自定義的eql?
示例使用==
來比較實例變量,這是一個恥辱。理想情況下,它將使用eql?
作爲一致性,與數組爲==
(如果其元素爲==
)以及數組爲eql?
(如果其元素爲eql?
)相同。最後,它應該提到Struct
,它爲你定義了體面的==
,hash
和eql?
。
中更加明確地感謝這裏的詳細解釋,這絕對有助於清除它 – Ricky 2013-04-24 23:32:24
例如, Array#hash
說 -
具有相同內容的兩個數組將具有相同的哈希碼(並將使用eql?進行比較)。
和Array#==
說:
平等 - 兩個數組相等,如果它們包含相同數量的元素,並且如果每一個元素等於(根據對象#==)在other_ary的對應元素。
返回true自我與他人是同一個對象,或者是具有相同內容的兩個陣列。
所以按照文件很清楚,eql?
速度更快,因爲它使用hash
值,與eql?
。而#==
做兩件事情 -
- 長度和
- 每個元素相等測試。
相關:http://stackoverflow.com/questions/10257096/why-is-faster-than-eql – 2013-04-24 22:36:23
@SemyonPerepelitsa:原來並不真正相關,但我很高興能夠回答這個棘手的問題: - ) – 2013-04-25 00:16:28
感謝您回答! – 2013-04-25 00:34:06