11 March 2013
Profiling Flash content with Adobe Scout gives you access to a huge amount of information, such as how long Flash spends rendering to the screen or executing specific APIs. Often, however, it's useful to group this information in ways that are semantically relevant to what you're doing, or send additional information to Scout about what's going on inside your code. This article covers the three ways you can send customized data to Scout, and explains how each method is useful.
If you're not sure how to profile your content with Scout, or what the different panels do, you should begin with the Scout Getting started guide.
There are two ways of sending Scout a simple metric–a message that something happened and when it happened. The first is the basic
trace() statement, and the second is the
Telemetry.sendMetric() API. In both cases you can send an arbitrary label and values, and Scout will show you when the message arrived in the context of what else was happening. Functionally these two methods are very similar, although they show up in Scout slightly differently. Using the methods is extremely simple:
myFunction( myValue++ ); trace( "Did something interesting: " + myValue ); myOtherFunction( myValue++ ); Telemetry.sendMetric( "Did something else", myValue );
trace() statements show up in the Scout Trace Log panel (see Figure 1). The trace log is dynamically updated as you select frames in the main timeline. Thus it's particularly useful if you trace high-level messages about the status of your content, such as "Finished logging in" or "Beginning level 2". To find those events in Scout, open the trace log and then click in the timeline and drag left or right.
When you call
sendMetric() the results show up show up in the Activity Sequence panel, along with trace statements (see Figure 2).
Currently, Scout doesn't do anything with the second value you pass to
sendMetric (except display it). So
sendMetric are functionally pretty similar, with trace being more useful due to the dedicated Trace Log panel. Right now the only real use for
sendMetric is if you want to track lots of low-level events without cluttering up the trace log. In the future though, additional functionality may be added to
sendMetric that makes it more useful for various tasks.
Note: It is a good idea to use reverse namespace notation (such as "com.example.MyMetric") for metric names, so that your metrics will be easily distinguishable from those used by any libraries you might import. That said, you can use any string you like, except strings starting with ".", which are reserved for native Flash Player use.
Normally Scout measures the time spent on various activities (such as rendering or script execution) that take place in the Flash runtime. Setting a custom span metric enables you to define new activities that are relevant to your specific content, such as "initializing enemies" or the like. The flow is simple: first save
Telemetry.spanMarker to a variable when you begin spending time on the activity you want to measure, and afterwards pass that marker to
Telemetry.sendSpanMetric(). For example, suppose you have one function that spends 20 milliseconds (ms) executing ActionScript commands and another that spends 20 ms calling Flash rendering APIs (such as
var marker1:Number = Telemetry.spanMarker; spendTimeOnAS3(20); Telemetry.sendSpanMetric("Doing some AS3", marker1); var marker2:Number = Telemetry.spanMarker; spendTimeRendering(20); Telemetry.sendSpanMetric("Doing Rendering", marker2); var marker3:Number = Telemetry.spanMarker; spendTimeOnAS3(20); Telemetry.sendSpanMetric("Doing some AS3", marker3);
The code above sends three different custom metric spans, two labeled as AS3 execution and one labeled as rendering. These metrics show up differently in Scout's various panels. If you select one frame and look in the Activity Sequence panel (see Figure 3), you'll see all three custom metrics listed in the sequence in which they were called. The overall time (20 ms) spent on each one is shown in the Total Time column. Notice the values in the Self Time, which reflects time spent only on a given activity, in contrast to Total Time, which refers to an activity and its child activities. Scout treats the
BitmapData.draw calls handled by the renderer as a child activity of the Rendering custom metric. That's why it doesn't have a self time of 20ms.
To see the metrics in the Summary panel, expand the ActionScript entry by clicking it (see Figure 4). Once you do this, custom metrics data will display as bright green in all Scout panels. You can also see in Figure 4 that the time spent rendering is shown as a separate activity from the custom metrics. That's because the summary panel shows each activity's self time, not their total time.
You can also select one frame or a span of frames and check the aggregate results of your custom span metrics. In the ActionScript panel you'll see the metrics as they occurred within your AS3 call stack, so you can determine which function or event caused the metrics to be executed. And in the Top Activities panel you can see the aggregate time spent on each metric as well as a count of how many times each one was encountered (see Figure 5).
In Figure 5 two frames are selected, and you'll notice that the Top Activities panel shows the time spent on custom metrics was 80ms and 40ms, while the ActionScript panel reports 71ms and 35ms. This is because the ActionScript panel reports data gathered by periodically checking (or sampling) the virtual machine, so the timing measurements are less accurate. The ActionScript panel is great for understanding the context in which your metrics were executed, but for the most accurate time data you should rely on any of the other panels.
One more note about timing—there is a small time cost associated with reporting custom metrics. If you measure a large number of them each frame, this can generate enough overhead to affect your performance data and make the timing data less accurate.
To sum up, it’s best to use span metrics to track the time spent on semantically related activities and
trace statements to keep track of relevant lone events. Usually you won't need to use the
sendMetric API unless you want to track lots of events without cluttering up the trace log, but it may become more useful in the future.
You may have noticed two more methods in the Telemetry class:
registerCommandHandler( commandName, handler ) unregisterCommandHandler( commandName )
Adobe is considering adding a feature to a future version of Scout that would enable the profiling tool to send messages to your content, which would catch the messages via these APIs. As of today (Scout v1.0), however, they don't do anything.
Now that you know how to track custom metrics, you can start defining metrics that are relevant to your content, helping you zero in on performance problems that much faster. If you have any trouble interpreting the results, or you want a deeper understanding of what's happening behind the data, see Understanding Flash Player with Adobe Scout.