Wan’t to get rid of your traces to trace? (Flex)


Update: to clearify I want to mention already here that this post regards using the Flex SDK, since the Adobe CS have an “Omit traces” checkbox which totally removes all traces in the bytecode as well.

I noticed a high FPS-loss in one of my applications when testing some Z-sorting in the Flash 10 3D functionality which I hadn’t been seing before. This even when using release mode when compiling! I had to use the profiler through Flash Builder 4 beta to track it down to a trace in the Z-ordering algorithm (just using a regular Painters Algorithm based on the actual Z-value compared to the root). /Update

What’s up with that trace draining performance even when compiling in release mode?

Believe it or not, but the bytecode regarding traces look identically no matter if you use release or debug compilation mode, it’s just up to the flashplayer itself to actually make something with the call to trace depending on the release mode.

So here’s the proof, and solution:

A normal constructor for a Main class:

public function Main():void 
{
	trace("Test");
}

So, you’re running your little flash-application in debug mode while developing, of course because you want to see the trace messages. But what happens behind the scene?
This is what the ABC2 byte-code looks like for the above Main constructor, notice the trace with 13, 15 and 17 in front (which by the way is the sum of instructions for the AVM2 engine).

function Main():void	/* disp_id -1*/
{
	// local_count=1 max_scope=1 max_stack=2 code_len=24
	0       debugfile     	"E:\temp\TraceTest\src;;Main.as"
	2       debugline     	13
	4       getlocal0     	
	5       pushscope     	
	6       debugline     	13
	8       getlocal0     	
	9       constructsuper	(0)
	11      debugline     	15
	13      findpropstrict	trace //find the trace function
	15      pushstring    	"Test" //the string to trace
	17      callproperty  	trace (1) //call the function
	20      pop           	          //end - start of next, 20-13 = 7 instructions for the AVM2 engine
	21      debugline     	16
	23      returnvoid    	
}

Okay, nothing weird here since its compiled with debug, but what really happens when we switch to release mode?
Well, mainly the compiler will remove the debugline, telling what line in the actual source-code (.AS files) the flashplayer executes the code for. This is the information shown in unhandled exceptions that gets thrown so you easily can find the broken code.

But, what about that trace?

This is the exact same code, only switched to release mode:

function Main():void	/* disp_id -1*/
{
	// local_count=1 max_scope=1 max_stack=2 code_len=13
	0       getlocal0     	
	1       pushscope     	
	2       getlocal0     	
	3       constructsuper	(0)
	5       findpropstrict	trace //Didn't I just tell you to go away by switching to release mode?
	7       pushstring    	"Test" //Even the strings are left intact
	9       callpropvoid  	trace (1) //And also the function call.... sigh
	12      returnvoid    	     //still adding upp to 12-5 = 7 instructions as well since it's the exact same code
}

But how can we solve this?
One solution could be to add a global flag in the main class and then use it as condition when to use the trace

private const DEBUG:Boolean = false;  //change to true when developing

But this would only make the release build to evaluate that flag to see if we want to trace or not,
so how about removing all traces by hand ? Not too funny when we want to continue to develop again.

The solution is called conditional compilation and is supported by the Flex compiler.
See Adobes reference here: http://livedocs.adobe.com/flex/3/html/help.html?content=compilers_21.html

The solution for this example:

public function Main():void 
{
	IFDEF::DEBUG {
		trace("Test");
	}
}

And by passing this to the compiler:

-define=IFDEF::DEBUG,false
//or
-define=IFDEF::DEBUG,true

we simply make the compiler remove the whole block of code within the { } when IFDEF:DEBUG is set to false

This produces the ABC2 byte-code as follows, nice and clean from the trace:

function Main():void	/* disp_id -1*/
{
	// local_count=1 max_scope=1 max_stack=1 code_len=6
	0       getlocal0     	
	1       pushscope     	
	2       getlocal0     	
	3       constructsuper	(0)
	5       returnvoid    	
}

, , , , , ,

  1. #1 by Nicolas on November 16, 2009 - 9:32 pm

    Flash CS4 has the “Omit trace actions” option in the publish settings. Sadly, this does not exist for the Flex compiler to my knowledge.

    Running a global search and replace to comment/uncomment any trace statements before compiling may also do the trick. This way the code would be removed completely from the SWF.

  2. #2 by Erik Karlsson on November 16, 2009 - 10:15 pm

    @Nicolas, yes you’re right about the Adobe CS which has the Omit trace checkbox. But most Flash development, at least to me and around me nowdays are either pure ActionScript using the Flex SDK or building applications on top of the Flex Framework. We’ll see if this change with CS5 which has promised a better code-editor :)

    Using the above version with a parameter to the compiler will remove the conditional block entirely from the swf and you can easily toggle it on and off when you want to continue the development.

  3. #3 by Nicolas on November 17, 2009 - 2:11 am

    Hi Erik, you are right about Flash Pro’s built in editor – It sucks. I’ve been using FDT for well over a year and couldn’t live without it.

    Compiler directives should work in FDT, I’ll test it in my next project ;-)

  4. #4 by Erik Karlsson on November 17, 2009 - 7:30 am

    I just updated the post with a section describing that this is only regards the Flex SDK more clearly to avoid confusion.

  5. #5 by Mem's on May 19, 2011 - 3:44 pm

    Or simply use this compiler argument:
    -compiler.omit-trace-statements=true

    Automatically remove all traces. I suppose Flash Pro use that argument when you check “Omit trace” checkbox

  6. #6 by www.5htp.co on January 30, 2013 - 3:11 pm

    I every time emailed this weblog post page to all my contacts, because if like to read it next my links will too.

(will not be published)