summaryrefslogtreecommitdiffstats
path: root/Modules/_collectionsmodule.c
diff options
context:
space:
mode:
authorRaymond Hettinger <python@rcn.com>2014-05-18 20:32:40 (GMT)
committerRaymond Hettinger <python@rcn.com>2014-05-18 20:32:40 (GMT)
commit507d997714424cbd1cf8dba21b26791eaefe4253 (patch)
treefaf06677a0fbe8ae353a3f04bf36abee784c86c2 /Modules/_collectionsmodule.c
parent4c5a187c0aa431b28d8e03d46f7583fddb6b365b (diff)
downloadcpython-507d997714424cbd1cf8dba21b26791eaefe4253.zip
cpython-507d997714424cbd1cf8dba21b26791eaefe4253.tar.gz
cpython-507d997714424cbd1cf8dba21b26791eaefe4253.tar.bz2
Add comment and make minor code clean-up to improve clarity.
Diffstat (limited to 'Modules/_collectionsmodule.c')
-rw-r--r--Modules/_collectionsmodule.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c
index c6c8666..b2783d2 100644
--- a/Modules/_collectionsmodule.c
+++ b/Modules/_collectionsmodule.c
@@ -1831,6 +1831,16 @@ _count_elements(PyObject *self, PyObject *args)
if (mapping_get != NULL && mapping_get == dict_get &&
mapping_setitem != NULL && mapping_setitem == dict_setitem) {
while (1) {
+ /* Fast path advantages:
+ 1. Eliminate double hashing
+ (by re-using the same hash for both the get and set)
+ 2. Avoid argument overhead of PyObject_CallFunctionObjArgs
+ (argument tuple creation and parsing)
+ 3. Avoid indirection through a bound method object
+ (creates another argument tuple)
+ 4. Avoid initial increment from zero
+ (reuse an existing one-object instead)
+ */
Py_hash_t hash;
key = PyIter_Next(it);
@@ -1848,13 +1858,13 @@ _count_elements(PyObject *self, PyObject *args)
oldval = _PyDict_GetItem_KnownHash(mapping, key, hash);
if (oldval == NULL) {
if (_PyDict_SetItem_KnownHash(mapping, key, one, hash) == -1)
- break;
+ goto done;
} else {
newval = PyNumber_Add(oldval, one);
if (newval == NULL)
- break;
+ goto done;
if (_PyDict_SetItem_KnownHash(mapping, key, newval, hash) == -1)
- break;
+ goto done;
Py_CLEAR(newval);
}
Py_DECREF(key);