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
- Misc/NEWS.d/next/Core and Builtins
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); |