summaryrefslogtreecommitdiffstats
path: root/Modules/_collectionsmodule.c
diff options
context:
space:
mode:
authorRaymond Hettinger <python@rcn.com>2014-05-03 23:41:19 (GMT)
committerRaymond Hettinger <python@rcn.com>2014-05-03 23:41:19 (GMT)
commit4b0b1accb57aabdd1b30dd445c2d530e9cdda65d (patch)
tree017a82239190233f82bfc9231f632ff9b96a00fc /Modules/_collectionsmodule.c
parent4b74fba62ff9e9733da01a55d4091b656324e969 (diff)
downloadcpython-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.c17
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);
}