Today I tried to outsource some of my "final" values (members of my class) from a class to an Enum. I ran the unittests I wrote and noticed, that the tests needed much longer to complete than before. When I put these "final" values back into the class, everything was back to old speed again. Here an example of how I accessed them when they were in the Enum:
class SpecialCharacters(Enum):
TONE_NUMBERS = ["0", "1", "2", "3", "4"]
Accessing it like this:
SpecialCharacters.TONE_NUMBERS.value
Example of accessing the values when they are in the class:
self.TONE_NUMBERS
So I wonder why my tests take 3x (!) as much time when I put the values in the Enum. It should be a simple call to another class' members, but that wouldn't make such a big difference I guess.
(The goal of outsourcing them was that they're available for other classes and those other classes don't have to access a class with which they have nothing to do.)
My python version is 3.4.
It's kind of slow. We were using enums a lot in our code, until we noticed that enum overhead takes up single digit percentages of our CPU time! Luckily, it only took a few hours to write a much faster implementation with almost the same functionality.
Python enums are useful to represent data that represent a finite set of states such as days of the week, months of the year, etc. They were added to Python 3.4 via PEP 435. However, it is available all the way back to 2.4 via pypy. As such, you can expect them to be a staple as you explore Python programming.
By convention, enumeration names begin with an uppercase letter and are singular. The enum module is used for creating enumerations in Python. Enumerations are created with the class keyword or with the functional API.
Because Python's enum. Enum does not provide ordering by default, ostensibly to eliminate C-style (mis-)treatment of enumerations as thin wrappers over integral types.
This is a known bug in Python 3.4's enum: https://bugs.python.org/issue23486
It's been "fixed" in Python 3.5, such that enum attribute lookup is only 3x slower than normal, instead of 20x.
To answer the question Why?
:
The original design for Enum
was to have members be virtual attributes. This means they were not kept in the Enum
class dictionary, which meant that every lookup possible had to first fail, after which __getattr__
would be called on the class and the member found.
So basically lots of busy work.
The fix was to put the members in the class dictionary when possible (which is most of the time).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With