diff options
author | Antoine Pitrou <solipsis@pitrou.net> | 2009-02-13 13:52:33 (GMT) |
---|---|---|
committer | Antoine Pitrou <solipsis@pitrou.net> | 2009-02-13 13:52:33 (GMT) |
commit | 76a4b896c4b976d2d17df0aa7cf5c982986f8771 (patch) | |
tree | 743fa6fa5fc179f2d4cd15aed7dbef3ab7163f95 /Objects | |
parent | 2c079297706e4ef6a47a80d68f6e38fddddf1728 (diff) | |
download | cpython-76a4b896c4b976d2d17df0aa7cf5c982986f8771.zip cpython-76a4b896c4b976d2d17df0aa7cf5c982986f8771.tar.gz cpython-76a4b896c4b976d2d17df0aa7cf5c982986f8771.tar.bz2 |
Issue #5186: Reduce hash collisions for objects with no __hash__ method by
rotating the object pointer by 4 bits to the right.
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/object.c | 22 |
1 files changed, 7 insertions, 15 deletions
diff --git a/Objects/object.c b/Objects/object.c index 9108fd4..8006fda 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -1072,23 +1072,15 @@ _Py_HashDouble(double v) long _Py_HashPointer(void *p) { -#if SIZEOF_LONG >= SIZEOF_VOID_P - return (long)p; -#else - /* convert to a Python long and hash that */ - PyObject* longobj; long x; - - if ((longobj = PyLong_FromVoidPtr(p)) == NULL) { - x = -1; - goto finally; - } - x = PyObject_Hash(longobj); - -finally: - Py_XDECREF(longobj); + 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; -#endif } long |