Feature or enhancement
Proposal:
__setitem__ and __delitem__ share the mp_ass_subscript slot. If a Python subclass of a C mapping overrides only one of them, slot_mp_ass_subscript() is used for both operations.
For example, collections.Counter overrides __delitem__ but inherits dict.__setitem__. Assigning an item looks up the inherited wrapper_descriptor and calls it through the generic tp_call path. Since PyWrapperDescr_Type does not support vectorcall, _PyObject_MakeTpCall() and wrapperdescr_call() each create a temporary argument tuple before reaching dict's C slot.
Reproducer:
from collections import Counter
from time import perf_counter_ns
obj = Counter()
start = perf_counter_ns()
for index in range(20_000_000):
obj[0] = index
print((perf_counter_ns() - start) / 1_000_000)
On macOS 15.7.1 arm64 with a release build of main (d856402e7176e5a03c5c578f0efc1be968be3257), using two warmups and nine alternating-order samples:
main: 1402.07 ms median (1376.93–1445.12 ms)
prototype: 859.97 ms median (846.24–902.74 ms)
The prototype calls the inherited C slot directly when lookup returns the expected unbound mapping slot wrapper, and otherwise keeps the existing call path. This reduced the benchmark time by 38.66%.
The relevant call-path files are unchanged at b062727097e997bcb900e11503d3248daac903da.
Has this already been discussed elsewhere?
This is a minor feature, which does not need previous discussion elsewhere
Links to previous discussion of this feature:
No response
Linked PRs
Feature or enhancement
Proposal:
__setitem__and__delitem__share themp_ass_subscriptslot. If a Python subclass of a C mapping overrides only one of them,slot_mp_ass_subscript()is used for both operations.For example,
collections.Counteroverrides__delitem__but inheritsdict.__setitem__. Assigning an item looks up the inheritedwrapper_descriptorand calls it through the generictp_callpath. SincePyWrapperDescr_Typedoes not support vectorcall,_PyObject_MakeTpCall()andwrapperdescr_call()each create a temporary argument tuple before reachingdict's C slot.Reproducer:
On macOS 15.7.1 arm64 with a release build of main (
d856402e7176e5a03c5c578f0efc1be968be3257), using two warmups and nine alternating-order samples:The prototype calls the inherited C slot directly when lookup returns the expected unbound mapping slot wrapper, and otherwise keeps the existing call path. This reduced the benchmark time by 38.66%.
The relevant call-path files are unchanged at
b062727097e997bcb900e11503d3248daac903da.Has this already been discussed elsewhere?
This is a minor feature, which does not need previous discussion elsewhere
Links to previous discussion of this feature:
No response
Linked PRs