From ef68790fdbf9201b9d8ba8e36fb0d1394a9ec931 Mon Sep 17 00:00:00 2001 From: hauntsaninja Date: Sat, 16 Jul 2022 19:42:44 -0700 Subject: [PATCH] gh-93910: optimise enum attribute access MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This halves access to attributes such as methods or _sunder_ name Benchmarked using: ``` from enum import Enum class Color(Enum): RED = "Red" BLUE = "Blue" GREEN = "Green" def f(): for _ in range(1000): Color.RED Color.BLUE Color.GREEN def g(): for _ in range(1000): Color.RED._name_ Color.BLUE._name_ Color.GREEN._name_ import timeit print(timeit.timeit('f()', number=10000, globals=globals())) print(timeit.timeit('g()', number=10000, globals=globals())) ``` As of today morning: ``` 6da988a46c λ ./python.exe bm_enum.py 1.499613167019561 1.5516562079428695 ``` As of the latest enum change #94913: ``` c20186c397 λ ./python.exe bm_enum.py 1.4998537090141326 16.095267291995697 ``` As of this PR: ``` gh-93910-micro λ ./python.exe bm_enum.py 1.4983433339511976 8.81327024998609 ``` --- Lib/enum.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Lib/enum.py b/Lib/enum.py index a4f1f09adae01c..8582763cd2828c 100644 --- a/Lib/enum.py +++ b/Lib/enum.py @@ -1102,11 +1102,11 @@ def __init__(self, *args, **kwds): pass def __getattribute__(self, name): - self_dict = super().__getattribute__('__dict__') - cls = super().__getattribute__('__class__') - value = super().__getattribute__(name) - if isinstance(value, cls) and name not in self_dict and name in self._member_names_: - raise AttributeError(" member has no attribute %r" % (cls.__name__, name)) + if name in super().__getattribute__('_member_names_'): + value = super().__getattribute__(name) + cls = super().__getattribute__('__class__') + if isinstance(value, cls) and name not in super().__getattribute__('__dict__'): + raise AttributeError(" member has no attribute %r" % (cls.__name__, name)) return super().__getattribute__(name) def _generate_next_value_(name, start, count, last_values):