Py_hash_t
_Py_HashPointer(void *p)
{
Py_hash_t x;
size_t y = (size_t)p;
/* bottom 3 or 4 bits are likely to be 0; rotate y by 4 to avoid
excessive hash collisions for dicts and sets */
y = (y >> 4) | (y << (8 * SIZEOF_VOID_P - 4));
x = (Py_hash_t)y;
if (x == -1)
x = -2;
return x;
}
type
中的tp_hash
插槽。)那里的注释似乎给出了不直接使用指针(即与id
相同的内容)的原因。实际上,引入该更改的提交在这里,并且说明了更改的原因是:
问题#5186:通过将对象指针向右旋转4位来减少没有 hash 方法的对象的哈希冲突。
其中提到了此问题,该问题更详细地解释了为什么要进行此更改。
id()
值会导致太多的冲突:In the issue 5169 discussion, Antoine Pitrou suggested that for an object
x without a `__hash__` method, `id()/8` might be a better hash value than
`id()`, since dicts use the low order bits of the hash as initial key, and
the 3 lowest bits of an `id()` will always be zero.
long
_Py_HashPointer(void *p)
{
long x;
size_t y = (size_t)p;
/* bottom 3 or 4 bits are likely to be 0; rotate y by 4 to avoid
excessive hash collisions for dicts and sets */
y = (y >> 4) | (y << (8 * SIZEOF_VOID_P - 4));
x = (long)y;
if (x == -1)
x = -2;
return x;
}