0

Hi I am looking for a way to speed up code execuation on the Pi in Python

I have a list that is 200 items each with 8 values

( X value , Y Value , X ofset , Y of set , Angle , Step , X cord , Y Cord )

Then I am carrying out some operations on them.

for x in range (0,500):
pygame.display.update(rects)
rects = [pygame.Rect(0,0,0,0)]

# Loop to update each star in turn, write the screen pixel back to background, draw new pixel and save the areas for the screen refresh task. 
for y in range (0 , 200 ):

    windowSurface.set_at(((StarA[y][6]), (StarA[y][7])), BLACK)
    rects.append(pygame.Rect(StarA[y][6],StarA[y][7],1,1))

    StarA[y][6] = int((StarA[y][0])*math.cos((((StarA[y][4])*math.pi)/180)))+StarA[y][2]
    StarA[y][7] = int((StarA[y][1])*math.sin((((StarA[y][4])*math.pi)/180)))+StarA[y][3]
    StarA[y][4] = StarA[y][4] + StarA[y][5]
    windowSurface.set_at(((StarA[y][6]), (StarA[y][7])), WHITE)
    rects.append(pygame.Rect(StarA[y][6],StarA[y][7],1,1))

so for the testing I am looping through the list 500 times, each time.

  1. clearing the screen of the item and saving the rect for later
  2. carrying out some transformations on the list items and incrementing values
  3. Drawing the new pixel and adding the rect for the screen refresh

It does work and while not completely smooth its not terrible but I want to know what ways I should look to improve it.

Now I know the raspberry Pi CPU is not the most powerful so is it possible to push any of this on to the GPU? Or are there better ways to deal with the transformation operation that just stepping though the list?

Still new to Python but would be grateful for some pointers.

3

I can't see you using y, so it's better to just loop over StarA and avoid a lot of array dereferencing

for star in StarA:

    windowSurface.set_at(((star[6]), (star[7])), BLACK)
    ...
    # Replace StarA[y] with star everywhere

Instead of recalculating math.pi/180 over and over, do it once and store that result in a variable

You may consider using numpy which can speed those types of calculations enormously

The GPU is out for the foreseeable future (unless you work for broadcom) as the internals are proprietry.

2
  • Better yet, pre-store arrays of sine and cosine for integer angles as a lookup table. If this is for display purposes, 1° resolution will likely be enough. (This was how we did it 20 years ago; with built-in FP it may not be quicker to still do this, but I don't know how ARMv6 shapes up.)
    – scruss
    Feb 8 '14 at 16:06
  • I was eventually thinking of using hash tables for the cos/sine, Even if it was for higher resolution / large screen I imagen doing it to a .1 or .01 presecision is still going to be fine and not a huge amount of memory. Cheers for the ideas people .
    – DevilWAH
    Feb 8 '14 at 22:46
1

In addition to what John La Rooy rightly said, I think maybe you should look at your Rect objects. It seems that for each of the 500 frames of the animation, you're:

  • deleting an array of 200 Rect objects
  • deleting each of these 200 Rect objects
  • creating another 200 Rect objects
  • appending each of these Rect objects to your array one at a time (probably having to resize the rects array as it goes)

You say it works fine now but it sounds quite inefficient and it will take longer and longer as you add stars and add frames.

To speed things up you should look at reusing the Rect objects, and using the move_ip() method to move each Rect object to where you want. Then you don't have to delete and destroy objects, reallocate memory, and create and resize arrays for each frame.

I don't know enough about pygame to know whether painting 200 Rects black and then 200 white is better or worse than just clearing the whole surface black, drawing your white dots and then calling pygame.display.update() (without passing all the rects).

2
  • updating the screen with the with the 200 rects is deffently smooth animation than a full screen refresh, but this may change using full screen with HW and double buffer.
    – DevilWAH
    Feb 8 '14 at 22:48
  • Hi, after profiling this script I can see that the time consuming processes are 1.) windowSurface.set_at.... and 2.) the screen refresh, although the set_at is by far the most time consuming. Any tips on a faster way to do this. I looked at the move_ip method but could not get it to work. I assume this is my misunderstanding standing of rects though.
    – DevilWAH
    Feb 10 '14 at 12:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.