pybind11 icon indicating copy to clipboard operation
pybind11 copied to clipboard

[BUG]: Time for `name` property on enum grows with enum size

Open niteria opened this issue 1 year ago • 0 comments

Required prerequisites

  • [X] Make sure you've read the documentation. Your issue may be addressed there.
  • [X] Search the issue tracker and Discussions to verify that this hasn't already been reported. +1 or comment there if it has.
  • [X] Consider asking first in the Gitter chat room or in a Discussion.

What version (or hash if on master) of pybind11 are you using?

>=2.10.0, same as pybind/python_example

Problem description

The Enum.name property implemented in #1345 has an unexpected performance characteristic. Namely the larger the enum the longer it takes.

I believe this function gets called https://github.com/pybind/pybind11/blob/8b48ff878c168b51fe5ef7b8c728815b9e1a9857/include/pybind11/pybind11.h#L1988 and it's on average O(n) in the size of the enum.

The example is synthetic, but I've run into this being a problem in a real code base.

Reproducible example code

I've created a reproducible example here: https://github.com/niteria/python_example/tree/linear-enum-name-repro

It just wraps 3 different sizes of enums and measures the time taken by enum.name.

https://github.com/niteria/python_example/commit/3b063004e24610b712bd64b3e752aeafc8732c55 is the only change on top of pybind/python_example.

To run:

~/tmp/python_example$ pip install .
~/tmp/python_example$ python test.py

Output on my computer:

$ python test.py 
Small time: 0.009021997451782227 seconds
Medium time: 0.31952929496765137 seconds
Large time: 3.216634511947632 seconds

Is this a regression? Put the last known working version here if it is.

Not a regression

niteria avatar Feb 20 '24 14:02 niteria