Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork33.7k
Closed
Description
Bug report
The performance of attribute lookup for type objects is worse than for other objects. A benchmark
import pyperfrunner=pyperf.Runner()setup="""class Class: def all(self): passx=Class()"""runner.timeit('hasattr x.all', "hasattr(x, 'all')", setup=setup)runner.timeit('hasattr x.__array_ufunc__', "hasattr(x, '__array_ufunc__')", setup=setup)runner.timeit('hasattr Class.all', "hasattr(Class, 'all')", setup=setup)runner.timeit('hasattr Class.__array_ufunc__', "hasattr(Class, '__array_ufunc__')", setup=setup) # worse performanceResults:
hasattr x.all: Mean +- std dev: 68.1 ns +- 1.1 nshasattr x.__array_ufunc__: Mean +- std dev: 40.4 ns +- 0.3 nshasattr Class.all: Mean +- std dev: 38.1 ns +- 0.6 nshasattr Class.__array_ufunc__: Mean +- std dev: 255 ns +- 2 nsThe reason seems to be that thetype_getattro always executesPyErr_Format, wheras for the "normal" attribute lookup this is avoided (seehere andhere)
Notes:
- The benchmark is from the python side, but we are working with the C-API
- The performance is important for numpy, seePERF: Improve performance of special attribute lookups numpy/numpy#21423
- Another location where this is a bottleneck:https://github.com/python/cpython/blob/v3.12.0a2/Lib/dataclasses.py#L1301
Your environment
- CPython versions tested on: Python 3.11.0a7+
- Operating system and architecture: Linux Ubuntu