[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [pygame] speed



> This is on BeOS R5, Athlon 600, 128 RAM.  I should also add that this is
> 640x480 in windowed mode.  My C++ version was developed in SDL also, so
> that's why I expected similar performance.  The first call I make in
> pygame is for a hw surface for my screen, so it should be getting
> it.



ok, i've had some time tonight to look through the code. before i get to 
specifics, i'd just like to point out that even though you pass a flag 
for HWSURFACE when you call set_mode(), it is unlikely you get it unless 
you pass FULLSCREEN too. not all platforms really support HWSURFACE, and 
the ones that do only can do it in FULLSCREEN mode (afaik).

also, just one other thing that comes to mind. you likely don't want to
mix HWSURFACE accelerated displays with RLEACCEL surfaces. RLEACCEL 
usually does speed up software blitting with colorkeys, but if you have 
hardware acceleration, it will already be much faster anyways. if the 
surface is RLEACCEL'd then SDL might even take longer as it occasianally 
needs to encode/decode the rle data.

anyways, on to your code...

whew, my first impression is that it might be a little over-designed. it 
shouldn't really be anything to worry about, but it takes awhile to 
learn my way through it. the version you sent me ran 26fps out of the 
zip. after a couple changes i've got it up to 40fps.

the first thing is pretty obvious. in the main loop you have a 
"pygame.time.delay()" call, which is waiting around for leftover time. 
this of course throws off FPS testing. :] commenting out the delay in 
SceneManager.loop() got me the most noticeable fix.

i did look at some profiling info, and also found that a large large 
chunk of time is spent in the Animation.draw. actually over 50% of my 
runtime is inside Sprite.draw(), (and that was even after i commented 
out the blit() calls). this means that blit() call is getting pounded.
it's a pretty simple function, so it wasn't hard for me to come up with 
some ideas.

def draw(self, dest, position):
   srcx = (self.index % self.imagesPerRow) * self.width
   srcy = (self.index / self.imagesPerRow) * self.height
   dest.blit(self.image, position, pygame.Rect(srcx, srcy, self.width, 
self.height))

the only thing it's doing here is calculating a source rectangle and 
blitting it. well it's is pretty easy to trim it. i added a variable 
"self.sourcerect" that is computed whenever self.index is changed. this 
turned out to be a noticeable win.


really though, before i'd recommend really pruning this change, i'd 
recommend a slightly different approach for your game objects. in your 
framework, i see even the ground tiles, with static images, are using 
this Animation class to store and draw their images. i'd think about 
making a "StaticImage" class, which worked the same as "Animation" but 
didn't really do all the work Animation is, just blit and store a single 
image. Even better might be to just make the ground tile objects keep 
the image themselves and blit it straight. it may not seem like a big 
deal, but when profiler says over 50% of the runtime is happening in 
this part of the code, i'd say making simpler cases for the places where 
  full Animation isn't needed would make an impact.

anyways, it's just a start. from the way things look i don't know if 
your straight port to python will ever be as fast as the C version. i'd 
secretly hope that using python would make it easier to do a 
smarter/faster design, so that the python code could come close to 
matching the C version.

hopefully this is enough to keep python open as an option for you. 
either way, i'm curious to see how python compares against C in your 
situation. if worse comes to worse, remember in 18 months computers will 
be twice as fast :]


____________________________________
pygame mailing list
pygame-users@seul.org
http://pygame.seul.org