[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