Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does this loop in python runs progressively slower?

In this code, there is a 4-D array of 13x13 images. I would like to save each 13x13 image using matplotlib.pyplot. Here for debugging purposes, I limit the outer loop to 1.

#fts is a numpy array of shape (4000,100,13,13)
no_images = 4000
for m in [1]:  
    for i in range(no_images):
        print i,
        fm = fts[i][m]
        if fm.min() != fm.max():
            fm -= fm.min()
            fm /= fm.max()  #scale to [0,1]
        else:
            print 'unscaled'
        plt.imshow(fmap)
        plt.savefig('m'+str(m)+'_i'+str(i)+'.png')

Saving 4000 images took more than 20 hours. Why is it this slow? If I limit the inner loop to the first 100 images, it takes about 1 minute. So the whole thing should be completed in 40 minutes, not over 20 hours! And I notice it seems to run progressively slower.

like image 734
ng0323 Avatar asked Oct 28 '15 08:10

ng0323


People also ask

Why for loops are slow in Python?

Java can 'sort of' run the instructions in your for loop in parallel with itself. Python has no concrete types and so the nature of the work to be done has to be decided at every instruction. This causes your entire computer to stop and wait for all the memory in all of your variables to be re-scanned.

WHY ARE FOR loops slower?

Originally Answered: Why are for loops so slow in Matlab? The loops incur much overhead of MATLAB, the interpreted language, calling many compiled code routines. It calls the compiled code routines each time it re-enters the body of the loop.

How do I make Python loops run faster?

A faster way to loop using built-in functions A faster way to loop in Python is using built-in functions. In our example, we could replace the for loop with the sum function. This function will sum the values inside the range of numbers. The code above takes 0.84 seconds.

What slows down a Python program?

If your Python code runs too fast, a call to time. sleep() is a simple way to slow down your code.


1 Answers

What you experience here is a memory leak: you keep creating instances of AxesImage objects (by repetitively calling plt.imshow) to the moment they can't fit into RAM; and then the whole thing begins swapping to disk, which is incredibly slow. To avoid memory leaks, you can either destroy AxesImage instance when you don't need it:

...
image = plt.imshow(fmap)
plt.savefig('m'+str(m)+'_i'+str(i)+'.png')
del(image)

Or, alternatively, you can create only one AxesImage, and then just change the data in it:

...
image = None
for m in [1]:  
    for i in range(no_images):
        ...
        if image is None:
             image = plt.imshow(fmap)
        else:
             image.set_data(fmap)
        ...
like image 117
Andrey Sobolev Avatar answered Sep 29 '22 10:09

Andrey Sobolev