bpo-8425: Fast path for set inplace difference when the second set is… · python/cpython@88ea166 (original) (raw)

File tree

2 files changed

lines changed

2 files changed

lines changed

Original file line number Diff line number Diff 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ù).
Original file line number Diff line number Diff line change
@@ -1463,9 +1463,25 @@ set_difference_update_internal(PySetObject *so, PyObject *other)
1463 1463 setentry *entry;
1464 1464 Py_ssize_t pos = 0;
1465 1465
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 +
1466 1478 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);
1468 1481 return -1;
1482 + }
1483 +
1484 +Py_DECREF(other);
1469 1485 } else {
1470 1486 PyObject *key, *it;
1471 1487 it = PyObject_GetIter(other);