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

Reply via email to