Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are python's for loops so non-linear for large inputs?

I was benchmarking some python code I noticed something strange. I used the following function to measure how fast it took to iterate through an empty for loop:

def f(n):
    t1 = time.time()
    for i in range(n):
        pass
    print(time.time() - t1)

f(10**6) prints about 0.035, f(10**7) about 0.35, f(10**8) about 3.5, and f(10**9) about 35. But f(10**10)? Well over 2000. That's certainly unexpected. Why would it take over 60 times as long to iterate through 10 times as many elements? What's with python's for loops that causes this? Is this python-specific, or does this occur in a lot of languages?

like image 982
user3002473 Avatar asked Feb 22 '15 19:02

user3002473


People also ask

Why doesn't Python have normal for loops?

The answer to your question is "Because they're different languages". They're not supposed to work alike. If they worked alike, they'd be the same language.

Are loops slow in Python?

Looping over Python arrays, lists, or dictionaries, can be slow. Thus, vectorized operations in Numpy are mapped to highly optimized C code, making them much faster than their standard Python counterparts.

How do you make Python loops faster?

Decrease the use of for loop As for loop is dynamic in python, it takes more time than while loop. So, use while loop instead of for loop.

How long does a for loop take Python?

We see that for creating same number of elements, for loop takes “14 seconds”, while list comprehension taks just about “9 seconds”. It is clear that for loop is much slower compared to list comprehension.


2 Answers

When you get above 10^9 you get out of 32bit integer range. Python3 then transparently moves you onto arbitrary precision integers, which are much slower to allocate and use.

In general working with such big numbers is one of the areas where Python3 is a lot slower that Python2 (which at least had fast 64bit integers on many systems). On the good side it makes python easier to use, with fewer overflow type errors.

like image 62
Thomas Ahle Avatar answered Jan 02 '23 04:01

Thomas Ahle


Some accurate timings using timeit show the times actually roughly increase in line with the input size so your timings seem to be quite a ways off:

In [2]: for n in [10**6,10**7,10**8,10**9,10**10]:
               % timeit f(n)
   ...:     
10 loops, best of 3: 22.8 ms per loop
1 loops, best of 3: 226 ms per loop # roughly ten times previous
1 loops, best of 3: 2.26 s per loop # roughly ten times previous
1 loops, best of 3: 23.3 s per loop # roughly ten times previous
1 loops, best of 3: 4min 18s per loop # roughly ten times previous

Using xrange and python2 we see the ratio roughly the same, obviously python2 is much faster overall due to the fact python3 int has been replaced by long:

In [5]: for n in [10**6,10**7,10**8,10**9,10**10]:
               % timeit f(n)
   ...:     
100 loops, best of 3: 11.3 ms per loop
10 loops, best of 3: 113 ms per loop
1 loops, best of 3: 1.13 s per loop
1 loops, best of 3: 11.4 s per loop
1 loops, best of 3: 1min 56s per loop

The actual difference in run time seems to be more related to the size of window's long rather than directly related to python 3. The difference is marginal when using unix which handles longs much differently to windows so this is a platform specific issue as much if not more than a python one.

like image 43
Padraic Cunningham Avatar answered Jan 02 '23 06:01

Padraic Cunningham