[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
Re: [pygame] is there a way to optimize this code?
My gut says this is most definitely the fastest way to go for small
numbers of snow flakes.
I suspect there is a certain point at which the numpy approach by Ian
wins out (especially if you can
optimize that a little more like Ian suggests, though I don't know
enough about numpy).
Some good tips to add to your bag of python optimization tricks:
- nested for-loops are bad news! move a loop into C whenever you can.
This can sometimes gain an order of magnitude
- numpy is fast, but you need to actually use its power. Just moving
the data into a numpy array and then operating on it in python won't
help
- local variables, avoiding attribute access, etc. are micro
optimizations. Use only as a last resort They'll rarely gain you more
than a few percent. It can make a difference in a tight loop, but
getting rid of the loop is usually much better.
- profile your code! This is the first thing to do, before you start
optimizing anything. I usually wrap the piece of code y I want to
profile in a function definition, and then run it with the cProfile
module, like so:
def x():
<code to profile>
cProfile.runctx('x()', globals(), {'x' : x}, 'prof_stats')
you can look at the profile data in a python session:
>>> import pstats
>>> s = pstats.Stats('prof_stats')
>>> s.sort_stats('time').print_stats()
take a look at the cProfile and pstats modules in the standard
library, they've saved my butt on numerous occasions.
Hugo
On Mon, Aug 17, 2009 at 10:54 AM, <don@xxxxxxxxxxxxxxxxx> wrote:
>
> Hi
>
> Note that didn't run any tests/profiling (no pygame installed on this machine).
> Anyway, here are my suggestions:
> 1) in "init()" instead of setting pixel per pixel to green use "pygame.draw.line()"
> 2) in "snowfall()" you check every pixel on every frame. this is most likly your bottleneck.
> what I would do ist have a list with the positions of all snowflakes so you know exactly
> where they are and don't have search the whole screen for them (especially if you only
> have 8). This should greatly increase performance (instead of 640*480 iterations you only
> need 8).
>
> After 2) you probably won't need the optimizations you implemented.
> Always remember "The Zen of Python". In this case: "Beautiful is better than ugly" and
> "Readability counts"!
>
>
> regards
> //Lorenz
>
>
>
> On Mon, 17 Aug 2009 02:33:30 -0400, Victor Noagbodji <noagbodjivictor@xxxxxxxxx> wrote:
>> hi, i'm following SDL tutorial here, http://sol.gfxile.net/gp/ch04.html
>>
>> this is the pygame equivalent. as you can see the code is not nice
>> looking. that's because i have tried all the optimization tricks i
>> know (local names, avoid dot operators, numpy array etc...) the result
>> is still awfully slow
>>
>> help.
>>
>> import numpy
>> import random
>> from sys import exit
>> from math import sin, cos
>>
>> import pygame
>> import pygame.event as event
>> import pygame.display as display
>>
>> from pygame.locals import *
>> from pygame import Surface
>> from pygame.time import get_ticks
>> from pygame.surfarray import pixels2d, blit_array, make_surface
>>
>> WIDTH = 640
>> HEIGHT = 480
>> RESOLUTION = (WIDTH, HEIGHT)
>>
>> def init(width, height, screen_array, green=int(0x007f00)):
>> for i in xrange(width):
>> sins = (sin((i + 3247) * 0.02) * 0.3 +
>> sin((i + 2347) * 0.04) * 0.1 +
>> sin((i + 4378) * 0.01) * 0.6)
>> p = int(sins * 100 + 380)
>> for j in range(p, height):
>> screen_array[i, j] = green
>>
>> def newsnow(width, height, screen_array, white=int(0xffffff)):
>> for i in xrange(8):
>> screen_array[random.randint(1, 638), 0] = white
>>
>> def snowfall(width, height, screen_array, white=int(0xffffff), black=0):
>> for j in xrange(height-2, -1, -1):
>> for i in xrange(1, width-1):
>> if screen_array[i, j] == white:
>> if screen_array[i, j+1] == black:
>> screen_array[i, j+1] = white
>> screen_array[i, j] = black
>>
>> def main():
>> pygame.init()
>>
>> width = WIDTH
>> height = HEIGHT
>>
>> screen_surf = display.set_mode(RESOLUTION)
>> screen_rect = screen_surf.get_rect()
>> screen_array = pixels2d(screen_surf)
>>
>> init(width, height, screen_array)
>>
>> white = int(0xffffff)
>> black = 0
>>
>> display.update(screen_rect)
>>
>> while True:
>> tick = get_ticks()
>>
>> newsnow(width, height, screen_array)
>> #snowfall(width, height, screen_array)
>>
>> for j in xrange(height-2, -1, -1):
>> for i in xrange(1, width-1):
>> if screen_array[i, j] == white:
>> if screen_array[i, j+1] == black:
>> screen_array[i, j+1] = white
>> screen_array[i, j] = black
>>
>> display.update(screen_rect)
>>
>> for e in event.get():
>> type = e.type
>> if type == QUIT:
>> exit()
>> elif type == KEYUP and e.key == K_ESCAPE:
>> return
>>
>> if __name__ == '__main__': main()
>>
>> --
>> paul victor noagbodji
>
>