New issue 2049: `enumerate` is relatively very slow under PyPy (but relatively fast under CPython) https://bitbucket.org/pypy/pypy/issue/2049/enumerate-is-relatively-very-slow-under
Jason Madden: While working on a PyPy compatible version of the `persistent` library, we noticed that the performance of the `enumerate` function is quite slow relative to maintaining the iteration count manually. In CPython, exactly the opposite is true and enumerate is faster. Tres Seaver [encouraged me to open a bug report.](https://github.com/zopefoundation/persistent/pull/20#discussion-diff-30593623) Given code similar to this (based on what Persistent was doing): ```python from collections import deque class Ring(object): def __init__(self): self.ring = deque() for i in range(3000): self.ring.append(i) def delete_with_enumerate(self, obj): for i, o in enumerate(self.ring): if o == obj: del self.ring[i] return 1 def delete_without_enumerate(self, obj): i = 0 for o in self.ring: if o == obj: del self.ring[i] return 1 i += 1 def test_enumerate(): ring = Ring() for i in range(3000, 0, -1): ring.delete_with_enumerate(i) def test_without_enumerate(): ring = Ring() for i in range(3000, 0, -1): ring.delete_without_enumerate(i) ``` Using the `timeit` module to run the two functions 100 times, taking the best of 20 runs (for a total run time for each function of nearly a minute on my machine) produces these results: | | PyPy 2.5.1 | CPython 2.7.9 | |------------|--------------:|-------------------| test_enumerate | 25.8ms | 352 ms | test_without_enumerate | 14.8ms| 414ms | % slowdown | 74% | -15% | In other words, using `enumerate` slows PyPy down by 74% (relative to counting by hand), whereas it speeds up CPython by 15%. PyPy is impressively fast here, of course, but removing `enumerate` speeds it up even more, which is the opposite of a CPython user's intuition and experience. _______________________________________________ pypy-issue mailing list pypy-issue@python.org https://mail.python.org/mailman/listinfo/pypy-issue