Performance in embeded / extended python

John Roth johnroth at ameritech.net
Wed Jul 4 16:08:19 EDT 2001


"Emmanuel Astier" <emmanuel.astier at winwise.fr> wrote in message
news:3b431024.15341289 at news.iway.fr...
> Hi,
>
>
> I embedded and extended python for a game, and I was REALLY
> disappointed by the performances I get...
>
> Every frame of my game ( should be 60 time by second ) I call my
> Python logical part from my C game with :

There's one thing that needs to be said right off - while there are
many successful commercial games that use a scripting language to
control the actual flow of the game, they don't, and I must repeat,
they don't call the script every frame. As you've noticed, it's just
too slow. It's the responsibility of the game engine (written in C
or C++, with Assembler assists as needed for performance) to
handle everything until, and only until, the engine needs a decision.

With 200 sprites, I presume you're doing some kind of arcade type
game - lots of stuff flashing around the screen, and the gameplayer is
pushing his hand-eye coordination to the limit. People don't use scripting
languages for that, except possibly for transitions.

Scripting languages are used where there is an extended storyline
embedded in the game, such as Adventure or RPG type games. The
script handles the storyline and transition, and the game engine handles
everything else.

For example, in Zork: Grand Inquisitor, there's a point early in the
game where the adventurer comes across a glass box on the wall, with the
sign "in case of adventure, break glass." The mechanism to solve this puzzle
requires a state machine with around five states and five or six inputs,
each
state transition requires that the scene is updated. There are literally
hundreds
of such situations in the game.

If you tried to do this in C or C++, with the inevitable rewrites as the
game
designers tried to tweak it this way and that to make the game a compelling,
memorable experiance, you'd run through your budget in no time flat.

>
> PyObject_CallFunction( LogicalEntryPoint, NULL );
>
> Logical Entry Point being a PyObject* pointing on the name of the
> function.

I presume that you've made sure that the function is preloaded in
memory at all times - it does not have to be reloaded from disk
or recompiled from a string.

> My function do only :
>
>     for i in range ( 0, NbTestSprites - 1 ):
>         ListOfSprites[i].setPos( 100, 100 )
>
> ie it sets the pos of 200 sprites.
> ListOfSprites is a tuple of 200 sprites, sprites is a extension class,
> and setPos one of its method.

"for i in range(...)" creates 101 objects each time it's executed: it
has to build a tuple, and objects for all numbers from 101 to 200.
(numbers from -1 to 100 are preallocated in the interpreter). It's
faster if this is done once, and then passed to the for loop:

foobar = range(0, NbTestSprites - 1)

for i in foobar:

This only works if foobar is stored somewhere where it doesn't have
to be recreated on each call.

>
> I'm using Swig to extend Python with my C functions ( I Tried Boost
> too, but there is even more overhead... )

Swig is intended to make extension more convenient. Convenience is
usually exactly opposite to performance. Do it by hand.

> This is _REALLY_ slow ( i run at around 1 Frame / second on a P733 ).
>
> 200 sprites is not so much...
>
> Have someone a clue of something I could have done wrong ?
>
> Can't extended python be faster ?
>
> Any help appreciated,
>
> thanks,
>
> Emmanuel
>
>
>





More information about the Python-list mailing list