[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [pygame] Python and Speed



On Thu, Apr 17, 2008 at 11:08 AM, Casey Duncan <casey@xxxxxxxxxxx> wrote:
Python is slow, it is an interpreted language geared toward rapid application development at the expense of execution speed. It is also designed to be highly portable, also at the potential expense of execution speed.
I realise that.  In my opinion, most of the time, nicer code comes before blazing speed. 
Sometimes (especially in things like graphics and simulations) there is no magic algorithm to make things more efficient. Many times the best you can do is O(N), O(N^2) or even O(2^N). In these cases, Python runs out of steam real fast (in fact any language runs out of steam fast with O(2^N) algorithms). This is especially pronounced in games where you have to perform operations over large arrays once per frame. This is typical in 3D graphics, physics and particle systems. What you must often do in such cases is move the inner loop of these operations into native code.
This is precisely the problem I have run into in one of my in-dev games--iterating over large arrays once per frame.  Actually, it is basically a collision detection algorithm--I have two arrays, both containing 3D points.  The points in one array must be tested with the points in the other to see how close they are.  If they are close enough, there is a collision.  Naturally, this means that for every point in one array, the other array must be iterated through and the 3D pythagorean theorem performed to each tested point.  
The easiest way to do this is to find a native library that already performs the operations you need.
This seems like a rather uncommon function--I haven't found that which I need.
This could be a generic library (like numpy) or something more specific (like pygame or ode). This is especially easy if the library already has a Python binding, if not you can make one using ctypes, pyrex or C directly. The downside here is the additional dependancies.

If nothing exists that does what you want, you'll need to write some native code yourself. First identify the slow code. Make sure there is no way to make it fast enough within Python (is there a better algorithm? etc). Then move this code into an extension, written however you prefer. Note it is fairly easy to create an extension module that defines some functions in C that can be imported into Python (especially if they just do number crunching), the most complex aspect is the memory management. Tools like pyrex can automate that for you, but don't give you as close control over the code. 
How do you write an extension module in C and call it from Python?   Someone gave some instructions earlier, but I found them too vague...
But before you do any of this, do some profiling (run your game under 'python -m cProfile') and see what's taking up the time. How much time per frame do you have for game logic? Is your logic too slow or is the drawing too slow? Honestly, my biggest problem with pygame is not python being too slow, but the fill rate of SDL being too slow. I can solve the former with optimization and extensions, but the latter requires much more compromise (lower res, smaller sprites, etc). The hard reality is that the CPU is often too slow for graphics work no matter what language you use (even highly tuned SIMD asm code). That's why we have dedicated graphics hardware designed for the task. Right now SDL doesn't really take advantage of that, and that's a big limitation.
For the game in question, I'm using OpenGL.  I have already established that the collision detection section is the slow part--I just don't know what to do about it.   
-Casey
Ian