You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Speed up hasattr(o, name) and getattr(o, name, default) #76725
I considered the idea of implementing _PyObject_GetAttrWithoutError() for bpo-31572, but dropped it because the code simplification was too small. But if this has performance benefits I'm +1 to implementing it. I'll update my still open PRs to use this API.
Activity
methane commentedon Jan 13, 2018
ABCMeta.new calls
getattr(value, "__isabstractmethod__", False)many times.cpython/Lib/abc.py
Lines 135 to 142 in 0f31c74
Since metaclass is used by subclasses, it checks all members of all subclasses (including concrete class).
But getattr() and hasattr() is inefficient when attribution is not found,
because it raises AttributeError and clear it internally.
I tried to bypass AttributeError when tp_getattro == PyObject_GenericGetAttr.
Here is quick micro benchmark:
Mean +- std dev: [python-master] 385 ns +- 2 ns -> [python-patched] 87.6 ns +- 1.6 ns: 4.40x faster (-77%)
(I added Ivan to nosy list because he may implement C version of ABC.)
serhiy-storchaka commentedon Jan 15, 2018
I considered the idea of implementing _PyObject_GetAttrWithoutError() for bpo-31572, but dropped it because the code simplification was too small. But if this has performance benefits I'm +1 to implementing it. I'll update my still open PRs to use this API.
methane commentedon Jan 16, 2018
I run pyperformance.
It seems django_template is significant faster.
# Without PGO+LTO
./python -m perf compare_to -G --min-speed=2 default.json patched.json
Slower (6):
Faster (10):
Benchmark hidden because not significant (44)
# With PGO+LTO
Faster (14):
Benchmark hidden because not significant (38)
methane commentedon Jan 16, 2018
New changeset 378edee by INADA Naoki in branch 'master':
bpo-32544: Speed up hasattr() and getattr() (GH-5173)
378edee
methane commentedon Jan 16, 2018
I confirmed django_template is
hasattr-heavy benchmark.Function was called by...
ncalls tottime cumtime
{built-in method builtins.hasattr} <- 1 0.000 0.000 /home/inada-n/local/py37/lib/python3.7/site-packages/django/apps/registry.py:20(init)
...
16318 0.003 0.003 /home/inada-n/local/py37/lib/python3.7/site-packages/django/utils/functional.py:81(prepare_class)
90000 0.065 0.065 /home/inada-n/local/py37/lib/python3.7/site-packages/django/utils/html.py:79(conditional_escape)
93200 0.064 0.064 /home/inada-n/local/py37/lib/python3.7/site-packages/django/utils/safestring.py:129(mark_safe)
90000 0.075 0.075 /home/inada-n/local/py37/lib/python3.7/site-packages/django/utils/safestring.py:149(mark_for_escaping)
vstinner commentedon Jan 16, 2018
Cool. I always wanted to implement something similar. Nice work Naoki!