Cocos2d v3 – addChild method make performance problems

| | August 4, 2015

i have currently a performance problem with the addChild method in cocos2d version 3.3. My scenario is currently that i have about ten CCNode which holds a bundle of other CCNode (about 500), i called those ten “Big Node”.

The childs of the “Big Node” has their own childs (about 3). Those CCNodes are sprites.

None of the childs from “Big Node” runs any actions. Everthing happens in their update method (if this relevant).

In my main scene i figured out which “Big Node” are on screen. If their is a new “Big Node” or the old one is not anymore visible on the screen i run this code:

self = mainScene
_allBigNodes = holds all avaible big nodes

        NSMutableArray * childsToRemove = [NSMutableArray arrayWithCapacity: _children.count];

        for(CCNode * child in _children){
            if([child isKindOfClass:[BigNode class]]){
                [childsToRemove addObject:child];
            }
        }

        for(CCNode * child in childsToRemove){
            [child removeFromParentAndCleanup:NO];
        }

        [childsToRemove removeAllObjects];

        for(int BigNodeIndex = _fromBigNodePosition; BigNodeIndex<=_toBigNodePosition; ++BigNodeIndex){

            BigNode * BigNode = [_allBigNodes objectAtIndex: BigNodeIndex];

            [self addChild: BigNode];

        }

The main screen has normaly maximum two childs. The above method works fine.

In concerning to the question: sometimes in my game i have some jittery movement. So i figure out with the profiling tool that the addChild method above cost between 60-100ms.

Running Time    Self                        Symbol Name
90.0ms   79.6%  0.0                         -[CCNode addChild:]
90.0ms   79.6%  0.0                          -[CCNode addChild:z:name:]
89.0ms   78.7%  0.0                           -[CCNode onEnter]
88.0ms   77.8%  0.0                            -[NSArray makeObjectsPerformSelector:]
88.0ms   77.8%  0.0                             -[CCNode onEnter]
72.0ms   63.7%  0.0                              -[NSArray makeObjectsPerformSelector:]
71.0ms   62.8%  0.0                               -[CCNode onEnter]
42.0ms   37.1%  0.0                                -[NSArray makeObjectsPerformSelector:]
42.0ms   37.1%  0.0                                 -[CCNode onEnter]
39.0ms   34.5%  0.0                                  -[CCScheduler scheduleTarget:]
38.0ms   33.6%  2.0                                   PrioritySearch
1.0ms    0.8%   1.0                                   DYLD-STUB$$objc::DenseMap<objc_object*, unsigned long, true, objc::DenseMapInfo<objc_object*> >::grow(unsigned int)
1.0ms    0.8%   0.0                                  -[CCNode physicsNode]
1.0ms    0.8%   0.0                                   -[CCNode physicsNode]
1.0ms    0.8%   1.0                                  objc_msgSend
1.0ms    0.8%   1.0                                  objc_object::sidetable_release(bool)
28.0ms   24.7%  0.0                                -[CCScheduler scheduleTarget:]
26.0ms   23.0%  1.0                                 PrioritySearch
1.0ms    0.8%   0.0                                 -[CCScheduler scheduledTargetForTarget:insert:]
1.0ms    0.8%   1.0                                 DYLD-STUB$$objc_msgSend
1.0ms    0.8%   0.0                                -[CCNode physicsNode]
1.0ms    0.8%   1.0                               DYLD-STUB$$objc_msgSend
16.0ms   14.1%  0.0                              -[CCScheduler scheduleTarget:]
14.0ms   12.3%  0.0                               PrioritySearch
2.0ms    1.7%   0.0                               -[CCScheduler scheduledTargetForTarget:insert:]
1.0ms    0.8%   0.0                            -[CCScheduler scheduleTarget:]
1.0ms    0.8%   1.0                           -[CCNode wasRunning:]

So my question would be: Is there a way to deactivate a ccnode or what is the best solution to handle this scenario of having many ccnodes or these “Big Nodes” which are offscreen?

Thank you in advance

Leave a Reply