6

ここで Ruby のチュートリアルを行っています: http://rubymonk.com/learning/books/4-ruby-primer-ascent/chapters/45-more-classes/lessons/105-equality_of_objects

==演算子をオーバーロードするとき、eql?メソッドとハッシュ メソッドも「高速」であるためオーバーロードする必要があると言っています。

ただし、本質的に同じ方法で 3 つすべてをオーバーロードしている場合、一方が他方よりもどのように高速でしょうか?

4

2 に答える 2

13

ほとんどの場合、==同じeql?結果になります。場合によっては、eql?は よりも厳密です==:

42.0 == 42 # => true
42.0.eql?(42) # => false

このため、定義する==と、おそらく定義もしたくなるでしょうeql?(またはその逆)。

ではなく、異なるキーを区別するためにHashクラスが使用する選択が行われました。だったかもしれませんが、きれいでした。eql?====eql?

eql?常に高価な呼び出しを行うことを避けるために、ハッシュ値は、2 つのオブジェクトeql?が同じハッシュ値を持つ必要があるという要件で計算されます。そのハッシュ値が保存されるため、将来の検索が非常に簡単になります。ハッシュ コードが一致しない場合、値はeql?...

そのため、 を定義するhash場合は、賢明な方法で定義する必要がありますeql?

==ほとんどの場合、ハッシュ値の計算はorとの比較よりもコストがかかることに注意してくださいeql?。ただし、ハッシュが計算されると、ハッシュが一致することを確認するのは非常に迅速です。

通常、ハッシュには非常に多くの比較が含まれるため、比較的コストのかかるハッシュ計算がキーごとに 1 回実行され、次にルックアップごとに 1 回実行されます。10 エントリのハッシュを想像してください。それを構築するにはhash、最初のルックアップが完了する前に を 10 回呼び出す必要があります。ただし、最初のルックアップは比較的高速です。 を 1 回呼び出したhash後、ハッシュ コードを非常に効率的に比較します (「インデックス化」されているため、実際にはこれよりも高速です)。eql?一致する場合でも、それが実際の一致であることを確認するために を呼び出す必要があります。実際、そうでない 2 つのオブジェクトがeql?同じハッシュを持つ可能性があります。唯一の保証は、2 つのオブジェクトがeql?同じハッシュを持つ必要があることですが、2 つの異なるオブジェクトも同じハッシュを持つ可能性があります。

代わりにを使用して同じことを行いたい場合は、検索ごとに をArray10 回呼び出す必要があります。eql?

価値があるのは、あなたがリンクしているRuby入門書がそれほど明確ではないと思います. の計算はコストがかかる可能性があるという事実を無視しているhashため、理にかなっている場合、つまり各要素が何度も比較されることが適切な仮定である場合にのみ実行されます。さらに、それが提供するカスタムの例がインスタンス変数の比較にeql?使用されているのは残念です。==理想的には、要素が である場合は配列が であり、要素がでeql?ある場合は配列であるのと同じように、一貫性のために使用します。最後に、どれが適切なを定義しているかについて言及する必要があります。====eql?eql?Struct==hasheql?

于 2013-04-24T21:46:19.507 に答える
3

たとえば、次のようにArray#hash言います-

同じ内容の 2 つの配列は、同じハッシュ コードを持ちます (そして、eql? を使用して比較します)。

Array#==言う:

等しい — 2 つの配列は、同じ数の要素を含み、各要素が (Object#== に従って) other_ary の対応する要素と等しい場合に等しいです。

Array#eql?言う

self と other が同じオブジェクトであるか、両方とも同じ内容の配列である場合に true を返します。

したがって、ドキュメントによると、値をeql?使用するほど高速であることは明らかです。一方、2つのことを行います-hasheql?#==

  1. 配列の長さと
  2. 各要素の等価性テスト。
于 2013-04-24T21:19:27.480 に答える