 <p>Use Psyco, for python2:</p> <pre><code>import psyco psyco.full() </code></pre> <p>Also, enable doublebuffering. For example:</p> <pre><code>from pygame.locals import * flags = FULLSCREEN | DOUBLEBUF screen = pygame.display.set_mode(resolution, flags, bpp) </code></pre> <p>You could also turn off alpha if you don't need it:</p> <pre><code>screen.set_alpha(None) </code></pre> <p>Instead of flipping the entire screen every time, keep track of the changed areas and only update those. For example, something roughly like this (main loop):</p> <pre><code>events = pygame.events.get() for event in events: # deal with events pygame.event.pump() my_sprites.do_stuff_every_loop() rects = my_sprites.draw() activerects = rects + oldrects activerects = filter(bool, activerects) pygame.display.update(activerects) oldrects = rects[:] for rect in rects: screen.blit(bgimg, rect, rect) </code></pre> <p>Most (all?) drawing functions return a rect.</p> <p>You can also set only some allowed events, for more speedy event handling:</p> <pre><code>pygame.event.set_allowed([QUIT, KEYDOWN, KEYUP]) </code></pre> <p>Also, I would not bother with creating a buffer manually and would not use the HWACCEL flag, as I've experienced problems with it on some setups.</p> <p>Using this, I've achieved reasonably good FPS and smoothness for a small 2d-platformer.</p>