Message389114
Calling methods and lookup up attributes when receiver is `super()` has extra cost comparing to regular attribute lookup. It mainly comes from the need to allocate and initialize the instance of the `super` which for zero argument case also include peeking into frame/code object for the `__class__` cell and first argument. In addition because `PySuper_Type` has custom implementation of tp_getattro - `_PyObject_GetMethod` would always return bound method.
```
import timeit
setup = """
class A:
def f(self): pass
class B(A):
def f(self): super().f()
def g(self): A.f(self)
b = B()
"""
print(timeit.timeit("b.f()", setup=setup, number=20000000))
print(timeit.timeit("b.g()", setup=setup, number=20000000))
7.329449548968114
3.892987059080042
```
One option to improve it could be to make compiler/interpreter aware of super calls so they can be treated specially. Attached patch introduces two new opcodes LOAD_METHOD_SUPER and LOAD_ATTR_SUPER that are intended to be counterparts for LOAD_METHOD and LOAD_ATTR for cases when receiver is super with either zero or two arguments.
Immediate argument for both LOAD_METHOD_SUPER and LOAD_ATTR_SUPER is a pair that consist of:
0: index of method/attribute in co_names
1: Py_True if super was originally called with 0 arguments and Py_False otherwise.
Both LOAD_METHOD_SUPER and LOAD_ATTR_SUPER expect 3 elements on the stack:
TOS3: global_super
TOS2: type
TOS1: self/cls
Result of LOAD_METHOD_SUPER is the same as LOAD_METHOD.
Result of LOAD_ATTR_SUPER is the same as LOAD_ATTR
In runtime both LOAD_METHOD_SUPER and LOAD_ATTR_SUPER will check if `global_super` is `PySuper_Type` to handle situations when `super` is patched. If `global_super` is `PySuper_Type` then it can use dedicated routine to perform the lookup for provided `__class__` and `cls/self` without allocating new `super` instance. If `global_super` is different from `PySuper_Type` then runtime will fallback to the original logic using `global_super` and original number of arguments that was captured in immediate.
Benchmark results with patch:
4.381768501014449
3.9492998640052974 |
|
Date |
User |
Action |
Args |
2021-03-19 20:57:57 | v2m | set | recipients:
+ v2m |
2021-03-19 20:57:57 | v2m | set | messageid: <1616187477.95.0.162642980766.issue43563@roundup.psfhosted.org> |
2021-03-19 20:57:57 | v2m | link | issue43563 messages |
2021-03-19 20:57:57 | v2m | create | |
|