Object Caching

Hello all.  Toward the end of today’s Corona Geek  Hangout (#177), I talked a little bit about the idea of ‘object caching’.

In a nutshell, object caching is the practice of keeping old display objects and re-using them instead of creating new display objects and destroying them when you are done.

No Caching

  • Create an object.
  • Interact with it a bit.
  • Destroy it via obj:removeSelf() or dipsplay.remove( obj )

Object Caching

  • Create an object.
  • Interact with it a bit.
  • Stop using it and move it somewhere off screen and/or hide it
  • Then, later when you need another object of the same sort, you simply move the object back on screen where you need it instead of creating a new one.

The question that exists is, “Is all this worth it? i.e. Does the performance gain make the extra coding worthwhile?”

My answer to this question for the longest time was, “probably not.”  I never use this technique, or at least not till recently when we started making the “Geometry Wars - Retro Evolved Clone”.

To further explore this idea, I made a basic testch bench: http://github.com/roaminggamer/CoronaGeek/raw/master/Hangouts/Tips_and_Tricks/objectCaching.zip

I am writing this post to ask people to run the test bench and to then post back their results below.

I will post my findings (and update them over time) as the next entry in this post.

Running the Test Bench

To run the test bench do the following:

  1. Build the app and install it on your device(s) of choice:
  2. Start the app.
  3. Wait of the frame rate counter to initialize
  4. Click 1 - For circle/rect/imagerect/sprite
  5. Click 400 
  6. Click ‘Use Caching’
  7. Wait…If the frame rate settles on a value below 60, write it down.  Otherwise KILL the app and choose a higher value during step 5.
  8. Once you have recorded a value, KILL the app and repeat the test using ‘No Caching’.  Wait and write down the number for that setting.

Do this test for 1 (circles), 2 (newRect), 3 (newImageRect), and 4 (newSprite).

At the end you should have 8 values written down.  Be sure to track your settings too.

Finally, post back your finding below.

If this is confusing, please see the GIF below and look at the values I’ve posted below for my devices.

cachingBench.gif

Thanks!

PS- This may not produce useful values in the simulator so don’t bother with that…

PPS - Forgot to say what the benchmark is doing:

For 500 object setting, it creates/restores 500 objects in frame 1, removes them in frame 2, creates/restores them anew in frame 3, removes them all in frame 4, and so on…

So, at an ideal rate of 60 FPS, this would equate to creating and destroying 15,000 objects per second… ideally.

Samsung Galaxy Tab 4

1 (circles) @ 500 - Caching ON ==\> 31 FPS AVERAGE 2 (rects)   @ 500 - Caching ON ==\> 33 FPS AVERAGE 3 (images)  @ 500 - Caching ON ==\> 33 FPS AVERAGE 4 (sprites) @ 500 - Caching ON ==\> 31 FPS AVERAGE 1 (circles) @ 500 - Caching OFF ==\> 25 FPS AVERAGE 2 (rects)   @ 500 - Caching OFF ==\> 31 FPS AVERAGE 3 (images)  @ 500 - Caching OFF ==\> 19 FPS AVERAGE 4 (sprites) @ 500 - Caching OFF ==\> 26 FPS AVERAGE

iPad Air Gen 1

1 (circles) @ 1000 - Caching ON  ==\> 51 FPS AVERAGE 2 (rects)   @ 1000 - Caching ON  ==\> 53 FPS AVERAGE 3 (images)  @ 1000 - Caching ON  ==\> 55 FPS AVERAGE 4 (sprites) @ 1000 - Caching ON  ==\> 52 FPS AVERAGE 1 (circles) @ 1000 - Caching OFF ==\> 35 FPS AVERAGE 2 (rects)   @ 1000 - Caching OFF ==\> 46 FPS AVERAGE 3 (images)  @ 1000 - Caching OFF ==\> 23 FPS AVERAGE 4 (sprites) @ 1000 - Caching OFF ==\> 33 FPS AVERAGE

I ran the object caching test on my iPad 3 and here are the results:

NC 1000 = 12fps
C 1000 = 16fps

NC 700 = 17fps
C 700 = 23fps

NC 300 = 36fps
C 300 = 46fps

NC 200 = 49fps
C 200 = 60fps

Ran the object caching on :

IPAD 2, 2nd Gen 

Setting 1    @400      c-on   39fps    c-off  29fps

Setting 2    @400      c-on   44fps    c-off  39fps

Setting 3    @400      c-on   44fps    c-off  19fps

Setting 4    @400      c-on   42fps    c-off  32fps

HTC 600    Android 4.2.2

Setting 1    @400      c-on   29fps    c-off  27fps

Setting 2    @400      c-on   34fps    c-off  26fps

Setting 3    @400      c-on   34fps    c-off  26fps

Setting 4    @400      c-on   33fps    c-off  29fps

* note on the android (HTC 600) … the frame rate top left corner…  would not lock in at 60FPS like on the iPad.  This kept fluctuating

between 63fps -67fps. 

Not sure if you wanted this tested on the smaller devices such as the HTC600, but as the screen size is very small, it was really really hard to read the text-output on the device.  So if others try and run it on the smaller device and have ‘old-guy’ eyes like mine, they will have a had time reading the results.  Maybe larger fonts and little more spacing for the items the user will need to touch, may make it easier on those smaller devices. 

Hope this helps.

Bob

@Bob,

Thanks.  Yeah, I made the ‘buttons’ very quickly using just text objects.  I didn’t want to distract users who looked at the code with a bunch of button code.

That said, the interface on this tester does suck. :slight_smile:  I too have trouble seeing it and tapping the right ‘button’ on a small screen.  Apologies and thanks again!

10" LG tablet Android 5.0.2

 1 Circle 2 Rec 3 Image 4 Sprite C NC C NC C NC C NC 100 62 67 61 71 63 52 62 76 300 50 36 51 49 46 28 49 35 500 35 26 38 32 33 20 34 26 1000 18 13 20 17 18 11 19 12 1500 12 9 13 11 12 8 12 9

What is the reason the app requires the plugins cc & maths2d?

7" Pendo tablet Android 4.4.2
idle 54fps

 1 Circle 2 Rec 3 Image 4 Sprite C NC C NC C NC C NC    100 54 55 54 58 54 44 54 60    300 36 30 40 36 39 26 38 30    500 27 21 30 26 30 19 29 21   1000 15 12 17 15 17 11 16 11   1500 11 8 12 10 12 8 11 8

Note it is faster at 100 objects in ‘No Caching’ mode than in menu mode

No reason, I simply stole the original main.lua, config.lua, and build.settings files from another project.  They won’t affect the run speed as I’m not using them.

just a suggestion (haven’t run the code):  might it not be better to use actual times (rather than trying to cause a framerate drop) to measure how long certain things take to do?  how long to create or destroy 15000 objects, or housekeep 15000 items into/out of your pool lists, or etc??

to suggest an obvious result before being “proved”:  if you really need 15000/sec then you will want to do some type of reuse.  why?  because a good portion of your timing difference will just be garbage collection.  true that creating objects takes time, but destroying them takes more – and is very like the primary reason you currently have to let your framerate “settle” (as the incremental gc tunes itself up to what must be a 100% load).  the amount of time to create/destroy or housekeep your pool shouldn’t vary significantly, but gc will.

also fwiw, call this an “entity pool” rather than an “object cache” and you’ll get more google hits for research purposes

Samsung Galaxy Tab 4

1 (circles) @ 500 - Caching ON ==\> 31 FPS AVERAGE 2 (rects)   @ 500 - Caching ON ==\> 33 FPS AVERAGE 3 (images)  @ 500 - Caching ON ==\> 33 FPS AVERAGE 4 (sprites) @ 500 - Caching ON ==\> 31 FPS AVERAGE 1 (circles) @ 500 - Caching OFF ==\> 25 FPS AVERAGE 2 (rects)   @ 500 - Caching OFF ==\> 31 FPS AVERAGE 3 (images)  @ 500 - Caching OFF ==\> 19 FPS AVERAGE 4 (sprites) @ 500 - Caching OFF ==\> 26 FPS AVERAGE

iPad Air Gen 1

1 (circles) @ 1000 - Caching ON  ==\> 51 FPS AVERAGE 2 (rects)   @ 1000 - Caching ON  ==\> 53 FPS AVERAGE 3 (images)  @ 1000 - Caching ON  ==\> 55 FPS AVERAGE 4 (sprites) @ 1000 - Caching ON  ==\> 52 FPS AVERAGE 1 (circles) @ 1000 - Caching OFF ==\> 35 FPS AVERAGE 2 (rects)   @ 1000 - Caching OFF ==\> 46 FPS AVERAGE 3 (images)  @ 1000 - Caching OFF ==\> 23 FPS AVERAGE 4 (sprites) @ 1000 - Caching OFF ==\> 33 FPS AVERAGE

I ran the object caching test on my iPad 3 and here are the results:

NC 1000 = 12fps
C 1000 = 16fps

NC 700 = 17fps
C 700 = 23fps

NC 300 = 36fps
C 300 = 46fps

NC 200 = 49fps
C 200 = 60fps

Ran the object caching on :

IPAD 2, 2nd Gen 

Setting 1    @400      c-on   39fps    c-off  29fps

Setting 2    @400      c-on   44fps    c-off  39fps

Setting 3    @400      c-on   44fps    c-off  19fps

Setting 4    @400      c-on   42fps    c-off  32fps

HTC 600    Android 4.2.2

Setting 1    @400      c-on   29fps    c-off  27fps

Setting 2    @400      c-on   34fps    c-off  26fps

Setting 3    @400      c-on   34fps    c-off  26fps

Setting 4    @400      c-on   33fps    c-off  29fps

* note on the android (HTC 600) … the frame rate top left corner…  would not lock in at 60FPS like on the iPad.  This kept fluctuating

between 63fps -67fps. 

Not sure if you wanted this tested on the smaller devices such as the HTC600, but as the screen size is very small, it was really really hard to read the text-output on the device.  So if others try and run it on the smaller device and have ‘old-guy’ eyes like mine, they will have a had time reading the results.  Maybe larger fonts and little more spacing for the items the user will need to touch, may make it easier on those smaller devices. 

Hope this helps.

Bob

@Bob,

Thanks.  Yeah, I made the ‘buttons’ very quickly using just text objects.  I didn’t want to distract users who looked at the code with a bunch of button code.

That said, the interface on this tester does suck. :slight_smile:  I too have trouble seeing it and tapping the right ‘button’ on a small screen.  Apologies and thanks again!

10" LG tablet Android 5.0.2

 1 Circle 2 Rec 3 Image 4 Sprite C NC C NC C NC C NC 100 62 67 61 71 63 52 62 76 300 50 36 51 49 46 28 49 35 500 35 26 38 32 33 20 34 26 1000 18 13 20 17 18 11 19 12 1500 12 9 13 11 12 8 12 9

What is the reason the app requires the plugins cc & maths2d?

7" Pendo tablet Android 4.4.2
idle 54fps

 1 Circle 2 Rec 3 Image 4 Sprite C NC C NC C NC C NC    100 54 55 54 58 54 44 54 60    300 36 30 40 36 39 26 38 30    500 27 21 30 26 30 19 29 21   1000 15 12 17 15 17 11 16 11   1500 11 8 12 10 12 8 11 8

Note it is faster at 100 objects in ‘No Caching’ mode than in menu mode

No reason, I simply stole the original main.lua, config.lua, and build.settings files from another project.  They won’t affect the run speed as I’m not using them.

just a suggestion (haven’t run the code):  might it not be better to use actual times (rather than trying to cause a framerate drop) to measure how long certain things take to do?  how long to create or destroy 15000 objects, or housekeep 15000 items into/out of your pool lists, or etc??

to suggest an obvious result before being “proved”:  if you really need 15000/sec then you will want to do some type of reuse.  why?  because a good portion of your timing difference will just be garbage collection.  true that creating objects takes time, but destroying them takes more – and is very like the primary reason you currently have to let your framerate “settle” (as the incremental gc tunes itself up to what must be a 100% load).  the amount of time to create/destroy or housekeep your pool shouldn’t vary significantly, but gc will.

also fwiw, call this an “entity pool” rather than an “object cache” and you’ll get more google hits for research purposes