Performance after batching worst

Hi! I am testing my game on simulator(easier to spot performance issues) about replacing LayerColor with Sprites so that i get automatic batching. What i do is that i add a small sprite and then i change the content size of that sprite to the required one and i noticed the following:

500 LayerColor → 60fps

500 Sprites - no content size / scale correction → 60fps

500 Sprites and setting content size → 30 fps

500 sprites and setting scale x2 → 60 fps

500 sprites and setting scale x3 → 30 fps

Can someone explain me why when i set the content size, performance is getting so worst? What is happenign internally? @zhangxm

I won’t recommend optimizing your game for a simulator (unless your target audience use simulators ). One main reason is that you cannot really blame your code for bad performance on your simulator there can be many reasons like computer is busy with other tasks like handling your editor request or music playback on youtube. Other reasons might include non optimized simulator (often simple instructions are transferred to other representations many times before executing). Moreover it gives non consistent results.

What you can do is that you define a low end device you are targeting and test your game on it. Or instead of launching game in simulator profile the desktop/mac build itself.

1 Like

Yes i agree but i only have available high end devices and all run 60fps so most times several choices that i make i dont know how they actually affect performance. If comparing in simulator under same conditions and one method is worst than other isnt this a valid test?

My real test is 350 LayerColors (no batching) vs 350 sprites (batching) + scaling or content size which one is best?

I think 350 sprites with batching is going to earn you better performance. If you post your code for this test, I’d be happy to try it out on some devices I have here.

@slackmoehrle The test is very simple just fill teh screen with as many sprites as possible to achieve less than 60fps. Then try to scale or chagne content size and see if it affects it. The test i would like to perform is to learn what is best:

  1. LayerColor with exact size
  2. Sprite and use exact image for each device so there is no scaling or content size change
  3. Sprite and change scaling
  4. Sprite and change content size

Try to adjust following code for an iphone 4 or 4s if possible.

    int x=5;
    int y=10;
    for (int i=0; i<25000;i++){
         //LayerColor *l = LayerColor::create(Color4B::RED, 2, 2);
        Sprite *l = Sprite::create("square1x1copy.png");
        l->setAnchorPoint(Vec2(0,0));
       //l->setColor(Color3B::RED);
       //l->setContentSize(Size(6,6));
        l->setScale(0.9);
        l->setPosition(Vec2(x,y));
        x+=l->getContentSize().width*l->getScale()+1;
        
        if (x>Director::getInstance()->getWinSize().width){
            x=0;
            y+=l->getContentSize().height*l->getScale()+1;
        }
        
        this->addChild(l);
    }

In my tests, real devices are unaffected by scaling or changing content size but i only tested on iphone xs max.

However, i would still like to have a fast simulator since I use it to test for devices that i dont have. Especially iphone x is slow as hell on simulator so if we can figure out what exactly makes it so slow, just for debugging i could disable some features to speed up things.

1 Like

Some ideas.


You may want to consider buying a used iPhone 4s or maybe even 5s by now on ebay or wherever possibly one with a broken screen (you can view screen through) if you want it real cheap performance testing device. You’ll use your current device(s) for visual accuracy (and all non-perf testing).


For testing purposes you could make a single image for the squares either offline (photoshop) or during initial load (by creating a RenderTexture and maybe writing that out as a cached temporary image file, to load in case the RenderTexture needs re-create). This is sort of how any “baking” process works. You could load this during simulator and use your current code for device testing.

You could look at using FastTMXTiledMap since it’s similar to how tilemap would render, though that’s a bit of a hack, so I’d recommend just writing your own specific background tiling renderer Node for your specific example.

Similarly the tile map concept is effectively just manual batching, and it should be as performant or better than relying on the auto-batching. Plus, you can pack all the squares into a single TriangleCommand and while the auto-batcher does make it possible to render only a single TriangleCommand as well there’s still some amount of CPU overhead.

If this is a background you could replace with a single LayerColor/gradient (similar to single sprite mentioned) or a few large screen-sized backgrounds if scrolling and see if it provides more performance on simulator.

You could do any of these things permanently, but you could also just test for simulator build.

If you find you’re not able to use this in c/c++ code then consider putting this in your .pch pre-compiled header and set a custom DEFINE specific to your game(s). Maybe cocos2d already has one?

#if TARGET_OS_SIMULATOR
    #warning Running in Simulator
#else
    #warning Running on Device!
#endif

If you aren’t using the latest XCode there’s a slight chance upgrading to the latest (you can even use the previous version side-by-side, though it’s a bit of work to do so).

@kerryk when setting content size or scale, more pixels will be rendered, which means fragment shader will be executed more times.

1 Like