[pypy-issue] Issue #2049: `enumerate` is relatively very slow under PyPy (but relatively fast under CPython) (pypy/pypy)

Jason Madden issues-reply at bitbucket.org
Tue May 19 19:10:21 CEST 2015


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.






More information about the pypy-issue mailing list