x = tuple(set([1, "a", "b", "c", "z", "f"]))
y = tuple(set(["a", "b", "c", "z", "f", 1]))
print(x == y)
プリント True
と時間の85%程度のハッシュのランダム化が有効になって。なぜ85%ですか?
x = tuple(set([1, "a", "b", "c", "z", "f"]))
y = tuple(set(["a", "b", "c", "z", "f", 1]))
print(x == y)
プリント True
と時間の85%程度のハッシュのランダム化が有効になって。なぜ85%ですか?
回答:
私はこの質問の読者が両方を読んだと想定します:
最初に注意すべきことは、ハッシュのランダム化はインタプリタの起動時に決定されるということです。
各文字のハッシュは両方のセットで同じになるため、衝突が発生した場合(順序が影響を受ける場合)だけが重要になります。
その2番目のリンクの控除により、これらのセットのバッキング配列が長さ8で始まることがわかります。
_ _ _ _ _ _ _ _
最初のケースでは、以下を挿入し1
ます。
_ 1 _ _ _ _ _ _
残りを挿入します:
α 1 ? ? ? ? ? ?
次に、サイズが32にリハッシュされます。
1 can't collide with α as α is an even hash
↓ so 1 is inserted at slot 1 first
? 1 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
2番目のケースでは、残りを挿入します。
? β ? ? ? ? ? ?
そして、1を挿入してみてください:
Try to insert 1 here, but will
↓ be rehashed if β exists
? β ? ? ? ? ? ?
そして、それはリハッシュされます:
Try to insert 1 here, but will
be rehashed if β exists and has
↓ not rehashed somewhere else
? β ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
したがって、反復順序が異なるかどうかは、βが存在するかどうかにのみ依存します。
βの確率は、5文字のいずれかが8 を法とする1にハッシュされる確率であり、法として1にハッシュされ、32を。
32を法とする1にハッシュするものはすべて、1を法とする8にもハッシュするため、32スロットのうち5つのうちの1つがスロット1にある可能性を求めます。
5 (number of letters) / 32 (number of slots)
5/32は0.15625なので、 2つのセット構造間でオーダーが異なる確率は15.625%です¹。
まったく奇妙なことではありませんが、これはまさにゼロピレウスが測定したものです。
¹技術的にもこれは明白ではありません。再ハッシュのために5つのハッシュのそれぞれを一意に見せかけることができますが、線形プロービングのため、実際には「束ねられた」構造が発生する可能性が高くなります...しかし、単一のスロットが占有されているかどうかのみを確認しているため、これは実際には影響はありません。