Skip to content

Commit

Permalink
Optimize set.pop() to advance a pointer instead of indexing. (GH-10429)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
rhettinger authored and miss-islington committed Nov 9, 2018
1 parent b83942c commit cf5863f
Showing 1 changed file with 8 additions and 7 deletions.
15 changes: 8 additions & 7 deletions Objects/setobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand All @@ -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;
}

Expand Down

0 comments on commit cf5863f

Please sign in to comment.