別の質問に対するゼロピレウスの答え 、私たちはそれを持っています
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にハッシュするものはすべて8を法として1にハッシュするので、32スロットのうち、5つのうちの1つがスロット1にある可能性を見つけたいと思います。
5 (number of letters) / 32 (number of slots)
5/32は0.15625であるため、2つのセット構成間で順序が異なる確率は15.625%です。
まったく奇妙なことではありませんが、これはまさにZero Piraeusが測定したものです。
¹技術的にも、これは明らかではありません。再ハッシュのために5つのハッシュのすべてを一意にふりをすることができますが、線形プローブのため、実際には「束ねられた」構造が発生する可能性が高くなります...実際には影響しません。