summaryrefslogtreecommitdiffstats
path: root/Objects/setobject.c
diff options
context:
space:
mode:
authorRaymond Hettinger <rhettinger@users.noreply.github.com>2018-11-09 10:31:56 (GMT)
committerMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2018-11-09 10:31:56 (GMT)
commitcf5863faabe011a61827b9b9982dba3d6a381f0f (patch)
treebff379775cf8c34899333006c05d78ef01d4f909 /Objects/setobject.c
parentb83942c755a78f6d917743b73ed87a8fd9f367de (diff)
downloadcpython-cf5863faabe011a61827b9b9982dba3d6a381f0f.zip
cpython-cf5863faabe011a61827b9b9982dba3d6a381f0f.tar.gz
cpython-cf5863faabe011a61827b9b9982dba3d6a381f0f.tar.bz2
Optimize set.pop() to advance a pointer instead of indexing. (GH-10429)
Gives approx 20% speed-up using clang depending on the number of elements in the set (the less dense the set, the more the speed-up). Uses the same entry++ logic used elsewhere in the setobject.c code.
Diffstat (limited to 'Objects/setobject.c')
-rw-r--r--Objects/setobject.c15
1 files changed, 8 insertions, 7 deletions
diff --git a/Objects/setobject.c b/Objects/setobject.c
index 42fe80f..ce50921 100644
--- a/Objects/setobject.c
+++ b/Objects/setobject.c
@@ -701,8 +701,7 @@ static PyObject *
set_pop(PySetObject *so, PyObject *Py_UNUSED(ignored))
{
/* Make sure the search finger is in bounds */
- Py_ssize_t i = so->finger & so->mask;
- setentry *entry;
+ setentry *entry, *limit;
PyObject *key;
assert (PyAnySet_Check(so));
@@ -711,16 +710,18 @@ set_pop(PySetObject *so, PyObject *Py_UNUSED(ignored))
return NULL;
}
- while ((entry = &so->table[i])->key == NULL || entry->key==dummy) {
- i++;
- if (i > so->mask)
- i = 0;
+ entry = so->table + (so->finger & so->mask);
+ limit = so->table + so->mask;
+ while (entry->key == NULL || entry->key==dummy) {
+ entry++;
+ if (entry > limit)
+ entry = so->table;
}
key = entry->key;
entry->key = dummy;
entry->hash = -1;
so->used--;
- so->finger = i + 1; /* next place to start */
+ so->finger = entry - so->table + 1; /* next place to start */
return key;
}