Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are Python Enums slow?

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.

like image 797
Zelphir Kaltstahl Avatar asked Jan 01 '15 23:01

Zelphir Kaltstahl


People also ask

Are enums slow in Python?

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.

Should I use enum in Python?

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.

Should enums be uppercase Python?

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.

Are Python enums ordered?

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.


2 Answers

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.

like image 101
BingsF Avatar answered Oct 03 '22 05:10

BingsF


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).

like image 32
Ethan Furman Avatar answered Oct 03 '22 05:10

Ethan Furman