performance issues


i have a problem with my first script: it is cpu ultraintensive.
cpu monitor is 98-100% every second when i launch it till i close it.
i think i am doing something wrong.

normally the examples i downloaded are getting no more than 60%.
for example Glow-Filter/ is no more than 45%.

this is my code:

from pandac.PandaModules import NodePath, TextNode, Point3
from direct.task import Task
from math import pi, sin, cos, sqrt, atan, tan, radians
from direct.showbase.ShowBase import ShowBase
import deliciousapi
class MyApp(ShowBase):

    def __init__(self):

        # base node
        node = NodePath("Sprite" ) 
        self.node = node

        def foo(task):
            return Task.cont
        taskMgr.add(foo, "SpinCameraTask")

    def centerTrackball(self, where): 
        bounds = where.getBounds() 
        center = bounds.getCenter() 
        radius = bounds.getRadius() 
        lens = self.camLens 
        fov = lens.getFov() 
        distance = radius / tan(radians(min(fov[0], fov[1]) / 2.0)) 
       , -distance)

    def create_tags(self, parent):
        print 'create_tags > call delicious api' 
        self.tags = []
        self.text_width = 0

        #dapi = deliciousapi.DeliciousAPI()
        #_tags = dapi.get_tags_of_user('nootropic.kint')
        _tags = eval( str(open("cashed_tags.log").read()) )
        print len(_tags)

        for k,v in _tags.items():
            c = self.getCard(parent, k, v) 
            if c:
                self.tags.append( c )
                self.text_width += c.getWidth()

        self.tag_min_count = min( _tags.values()  )
        self.tag_max_count = max( _tags.values()  )

    def tags_in_grid(self, leading = 1):
        column = sqrt( self.text_width + (leading)*len(self.tags) )
        x = y = z = 0
        for c in self.tags: 
            if x>column:
                x = 0
                z += leading 
            x+= 3
            c.nodePath.setPos(x, y, z)
            x += c.getWidth()

    def getCard(self, parent, string, count):
        except UnicodeEncodeError:
            print 'MyApp::getCard() - handling UnicodeEncodeError: ', string
            return None
            tag = Tag(string, count)
            return tag

class Tag:
    def __init__(self, string, count):
        self.string = string
        self.count = count

        text = TextNode('node name')
        text.setText(string)  #"Every day in every way I'm getting better and better.")
        self.textNode = text
        self.nodePath = None

    def attachToScenegraph(self, parent):
        nodePath = parent.attachNewNode(self.textNode)
        self.nodePath = nodePath
        return nodePath

    def getWidth(self): return self.textNode.getWidth()
    def getHeight(self): return self.textNode.getHeight()

app = MyApp()
print 'am i here?'

it is a simple tag cloud (i have to implement some 3d deformation, i’m on this project only from few days) and now i’m testing it with 1284 tags.
ok 1284 could be a big number but it is only static text… nothing complicated IMHO…
and for my project i want to do more than one visualization 1284*n …

where am i wrong?
are there some smart ways to do it? mayebe TextNode is not the better tool for visualizing tags?

if you want to test it i can give you the test-file of my tags, but i simply done something like:

$ python
>>> f = open('somefile.log', 'w')
>>> d = { 'hudge_dict_here':12345 }
>>> f.write(str(d))
>>> f.close()

ps: any other kind of advice on writing panda3d-code is nicly excpeted

First, a 100% cpu utilization is not an indication of performance problems. This is actually normal for a 3-D app. You’ve got a working CPU, don’t be afraid to use all of it.

The more useful measure of performance issues is frame rate. But this is a surprisingly complicated subject. If you have video sync enabled (sync-video 1 in your Config.prc file), then your frame rate will be locked to your video refresh rate, and you’ll never see a frame rate that’s faster than (say) 60fps. You also might occasionally see less than 100% cpu utilization if your unlocked frame rate would be higher than 60fps, which is what you must be seeing with the samples. But to measure frame rate accurately, you need to have video sync disabled (sync-video 0 in your Config.prc file), which means that your frame rate will go as high as it can, and your cpu utilization will always be 100% no matter what. This is where you need to do performance analysis.

Now, you can show the frame rate easily with show-frame-rate-meter 1 in your Config.prc. Or, for more precise analysis of performance bottlenecks, you need to use PStats.

But as I said, I have no idea whether you actually have a performance issue or not–you don’t say what your frame rate is, or what frame rate you want to target. Maybe your performance is fine as it is.

That said, you are pushing a limit with 1284 separate objects. Modern graphics cards card render many millions of vertices without sweating, but only if they are distributed among no more than a few hundred individually addressable objects. The general rule of thumb is no more than 300 objects if you wish to maintain 60fps, or no more than 600 to maintain 30fps. With 1200 you should expect somewhere around 15fps.

If you want to exceed this number of separate objects, you have to start resorting to tricks. One possible trick is to put all of them under a RigidBodyCombiner. This lets you go higher than the usual limit, but only if there are relatively few vertices for each object. There is more information on this object in the manual and in the forums.


show-frame-rate in Config.prc show 57 fps…

So you’re doing fine.