diff options
author | Raymond Hettinger <python@rcn.com> | 2014-05-03 23:41:19 (GMT) |
---|---|---|
committer | Raymond Hettinger <python@rcn.com> | 2014-05-03 23:41:19 (GMT) |
commit | 4b0b1accb57aabdd1b30dd445c2d530e9cdda65d (patch) | |
tree | 017a82239190233f82bfc9231f632ff9b96a00fc /Modules/_collectionsmodule.c | |
parent | 4b74fba62ff9e9733da01a55d4091b656324e969 (diff) | |
download | cpython-4b0b1accb57aabdd1b30dd445c2d530e9cdda65d.zip cpython-4b0b1accb57aabdd1b30dd445c2d530e9cdda65d.tar.gz cpython-4b0b1accb57aabdd1b30dd445c2d530e9cdda65d.tar.bz2 |
Issue #21101: Eliminate double hashing in the C code for collections.Counter().
Diffstat (limited to 'Modules/_collectionsmodule.c')
-rw-r--r-- | Modules/_collectionsmodule.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c index 0ab4156..c6c8666 100644 --- a/Modules/_collectionsmodule.c +++ b/Modules/_collectionsmodule.c @@ -1831,18 +1831,29 @@ _count_elements(PyObject *self, PyObject *args) if (mapping_get != NULL && mapping_get == dict_get && mapping_setitem != NULL && mapping_setitem == dict_setitem) { while (1) { + Py_hash_t hash; + key = PyIter_Next(it); if (key == NULL) break; - oldval = PyDict_GetItem(mapping, key); + + if (!PyUnicode_CheckExact(key) || + (hash = ((PyASCIIObject *) key)->hash) == -1) + { + hash = PyObject_Hash(key); + if (hash == -1) + goto done; + } + + oldval = _PyDict_GetItem_KnownHash(mapping, key, hash); if (oldval == NULL) { - if (PyDict_SetItem(mapping, key, one) == -1) + if (_PyDict_SetItem_KnownHash(mapping, key, one, hash) == -1) break; } else { newval = PyNumber_Add(oldval, one); if (newval == NULL) break; - if (PyDict_SetItem(mapping, key, newval) == -1) + if (_PyDict_SetItem_KnownHash(mapping, key, newval, hash) == -1) break; Py_CLEAR(newval); } |