Skip to content

Commit 88ea166

Browse files
authored
bpo-8425: Fast path for set inplace difference when the second set is large (GH-15590)
1 parent 4901fe2 commit 88ea166

File tree

2 files changed

+20
-1
lines changed

2 files changed

+20
-1
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Optimize set difference_update for the case when the other set is much
2+
larger than the base set. (Suggested by Evgeny Kapun with code contributed
3+
by Michele Orrù).

Objects/setobject.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1463,9 +1463,25 @@ set_difference_update_internal(PySetObject *so, PyObject *other)
14631463
setentry *entry;
14641464
Py_ssize_t pos = 0;
14651465

1466+
/* Optimization: When the other set is more than 8 times
1467+
larger than the base set, replace the other set with
1468+
interesection of the two sets.
1469+
*/
1470+
if ((PySet_GET_SIZE(other) >> 3) > PySet_GET_SIZE(so)) {
1471+
other = set_intersection(so, other);
1472+
if (other == NULL)
1473+
return -1;
1474+
} else {
1475+
Py_INCREF(other);
1476+
}
1477+
14661478
while (set_next((PySetObject *)other, &pos, &entry))
1467-
if (set_discard_entry(so, entry->key, entry->hash) < 0)
1479+
if (set_discard_entry(so, entry->key, entry->hash) < 0) {
1480+
Py_DECREF(other);
14681481
return -1;
1482+
}
1483+
1484+
Py_DECREF(other);
14691485
} else {
14701486
PyObject *key, *it;
14711487
it = PyObject_GetIter(other);

0 commit comments

Comments
 (0)