[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
Re: [pygame] fast sqrt? and profiling
hi,
you'll want to use a spacial hash.
Like this quadtree for example:
http://www.pygame.org/project/752/
cu!
On Wed, Jan 21, 2009 at 4:27 PM, Jake b <ninmonkeys@xxxxxxxxx> wrote:
> I'm writing a prototype, where I want a bunch of 'blobs', that clump/swarm,
> yet seperate. ( they keep min distance from each other, they don't overlap (
> or at least don't stay) )
>
> What I am doing, is every 250ms calculate each units neighbors. ( then,
> every loop, move away from each cached neighbor. ) My FPS stays around 26-30
> until I get 62+ units, then it drops like a stone. [ every Unit() waits 250
> for its update, I calc just it, not all Units. ]
>
> From profiling ( and testing ) I know the function to calculate locals (
> neighbors ) is causing most of the slowdown.
>
> 1) Is there a suggested fast sqrt module thats portable?
>
> 2) Is it bad to use isinstance in CPU intensive loops? ( ie: function
> list_type() )
>
> 3) it looks like euclid.Vector2.__sub__ is taking a lot of time. Is this
> abnormally high? or expected? Meaning should I be using a different lib for
> speed? [ that particular function uses isinstance() ]
>
> 4) Do you have some useful profile queries you've found?
>
> 5) Should I be staggering the dist() calls among multiple game updates()? [
> sort of am indirectly, but no enforcement. ] Or decouple physics from
> graphics ?
>
> Heres the functions I mentioned above:
>
> def calc_local(self):
> """re-calc 'who are my neighbors' to cache for later."""
> l = [] #first, get list of neighbors
>
> for u in self.game.units.list_type(Unit):
> if u == self: continue # don't collide self.
> if collide_circle( self.loc, u.loc, self.rad+self.local, u.rad):
> l.append(u)
> self.local_cache = l
>
> def list_type(self, t):
> """get list of units by class type. example: .list_type(Unit)"""
>
> l = []
> for u in self.units:
> if isinstance(u, t): l.append(u)
>
> Here's the profiling I'm basing this on:
> profile output: ( query = "p.sort_stats('time').print_stats(10)" )
>
> Ordered by: internal time
> List reduced from 311 to 10 due to restriction <10>
>
> ncalls tottime percall cumtime percall filename:lineno(function)
> 388 2.652 0.007 2.652 0.007 {built-in method tick}
> 1446 1.185 0.001 3.656 0.003 main.py:151(calc_local)
> 98318 0.790 0.000 1.242 0.000
> C:\Python25\lib\euclid.py:172(__sub__)
> 80355 0.538 0.000 2.071 0.000
> C:\jake_root\data\py\jake_includes\jakelib\util.py:49(dist)
> 194 0.520 0.003 0.520 0.003 {pygame.display.flip}
> 98583 0.497 0.000 0.681 0.000
> C:\Python25\lib\euclid.py:243(__abs__)
> 80355 0.391 0.000 2.462 0.000
> C:\jake_root\data\py\jake_includes\jakelib\util.py:70(collide_circle)
> 147359 0.348 0.000 0.348 0.000 {isinstance}
> 147253 0.338 0.000 0.338 0.000
> C:\Python25\lib\euclid.py:90(__init__)
> 12175 0.288 0.000 0.694 0.000
> C:\Python25\lib\warnings.py:24(warn)
>
>
> I know its a lot of questions, that's why I numbered it to simplify replies.
> Thanks for the help.
> --
> Jake
>