Mar 25 2009

Player 10 Performance Gotcha - Sneaky Surfaces

Published by Corey at 4:53 am under Technology, Work

When optimizing a production application, regardless of the SDK or technology used to build it, it’s important to understand the performance characteristics of the various APIs, primitives, and data structures that make up your SDK. When becoming proficient with a given platform it’s inevitable that you stumble upon nuances, inefficiencies, or just plain bugs…and over time your learn to “work with” (or around) said limitations.

Here’s one of the “plain ol’ bugs” you should be aware of when scrubbing your Flash or Flex application of performance issues.

Take the following code snippet towards the end of this post… Pretty simple, just creates a couple hundred Sprite instances, applies a quick opaque fill, and adds them to the stage. Taking a look at System.totalMemory, memory increases by about ~500K. Nothing mysterious.

Now, imagine we were to ask the player to cache each Sprite instance as a bitmap, e.g. via:

    currentSprite.cacheAsBitmap = true;

So for 250 display object instances, one would expect that the resulting ~ 3MB of memory usage sounds about right (32 bpp RGBA buffers). Again, nothing mysterious.

  

Now, let’s run the same test, but instead of setting cacheAsBitmap… what if we simply read the value of cacheAsBitmap for each Sprite instance:

    var test:Boolean = currentSprite.cacheAsBitmap;

Whoa! Again, we see ~ 3MB worth of surface allocations! For simply reading the property?!

Beware, this issue also affects a few other properties, some that may make it even more likely you’ll run into this… For example, simply asking a display object whether or not it has a scrollRect will cause a back buffer to be allocated for that object. Testing the opaqueBackground property also results in a similar fate.

Note: The problem as described currently affects the production Player 10 versions (10.0.12.36 and 10.0.22.87). The issue itself has been addressed and should be taken care of in the next non-incremental release of the player. Just tread lightly. :)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical"
    creationComplete="updateMem()">
 
    <mx:Script>
    <![CDATA[
        [Bindable]
        private var totalMem:String;
 
        private function startTest():void
        {
            for (var i:int = 0; i < 250; i++)
            {
                var currentSprite:Sprite = new Sprite();
                currentSprite.graphics.beginFill(0x000000);
                currentSprite.graphics.drawRect(0,0,300,100);
                currentSprite.graphics.endFill();
               
                // Uncomment to allocate surfaces for each Sprite instance (+ ~3MB).
                //currentSprite.cacheAsBitmap = true;
               
                // Uncomment to (surprisingly) take the same surface hit (+ ~3MB)
                //var test:Boolean = currentSprite.cacheAsBitmap;
                //var test2:Object = currentSprite.scrollRect;
                //var test3:Object = currentSprite.opaqueBackground;
               
                canvas.rawChildren.addChild(currentSprite);
            }
            System.gc();
            callLater(updateMem);
        }
       
        private function updateMem():void
        {
            totalMem = String(System.totalMemory / 1024) + " KB";
        }
    ]]>
    </mx:Script>
 
    <mx:Canvas id="canvas" width="300" height="100" />
    <mx:Button label="Start Test" click="startTest()" />
    <mx:Label text="Total Memory: {totalMem}"/>

</mx:Application>

One Response to “Player 10 Performance Gotcha - Sneaky Surfaces”

  1. Coreyon 07 Jan 2010 at 4:29 am

    For inquiring minds..this issue has been fixed in all production Flash players…

Trackback URI | Comments RSS

Leave a Reply