Hack 69 Benchmark Runtime Performance

figs/moderate.gif figs/hack69.gif

The Flash Bandwidth Profiler and third-party tools provide estimates of a Flash project's download time. Benchmark runtime performance to optimize playback as well.

The Flash Bandwidth Profiler and the third-party WebSpeed Simulator [Hack #66] calculate estimated download times, but they don't address runtime performance. Whereas the former varies with connection speed, the latter depends on the processing power of the playback machine. The user's overall experience is determined by a combination of the download times and runtime performance. It makes sense to make intelligent decisions about the trade-off between the two, as when substituting bitmaps for vectors [Hack #72] .

Runtime performance is inherently judged relative to the target frame rate, which is chosen by the Flash developer. If Flash can draw everything required by the time it is supposed to display the next frame, then it doesn't necessarily matter whether Flash had time to spare. However, this standard can overlook problems that might appear if you decide to increase the frame rate. You'd rather know which graphics are taking the longest to animate and which ActionScript is taking the longest to execute, so you can optimize each operation to reserve processor time for other things, like audio playback.

I use the following code to benchmark the effects of optimization. It uses a 1-millisecond interval, created with setInterval( ) [Hack #27], rather than an onEnterFrame event, which is tied to the frame rate. This forces Flash to redraw the screen as fast as it can, but it won't run every millisecond (perhaps every three milliseconds) due to performance limitations.

function animate(target) {
  // Animation script to move target clip across the Stage.
  target._x = (target._x + 1) % 400;
  updateAfterEvent( );
function controller( ) {
  // Display average redraw time (in ms).
  trace(clip[clipPointer]+ " " + 20000/count);
  // Animate next clip for 20 seconds (if there 
  // is another clip still to test).
  if (clipPointer < clip.length) {
    count = 0;
    animater = setInterval(animate, 1, clip[clipPointer]);
  } else {
  // If there is no other clip to test, stop.
// Setup
var clip:Array = new Array( );
var clipPointer:Number = 0;
var count:Number = 0;
clip[0] = clip01;
clip[1] = clip02;
clip[2] = clip03;
var animater:Number = setInterval(animate, 1, clip[clipPointer]);
var timer:Number = setInterval(controller, 20000);

In the preceding code, if clip01, clip02, and clip03 are three instances of a movie clip (for example, three versions of the same shape with different levels of curve optimization applied via the ModifyShape submenu), the code will animate each instance as fast as it can for 20 seconds. It returns the average time to redraw the movie clip in milliseconds, and this can be used to make a comparison between the clips.

The preceding code is designed to benchmark reasonably complex shapes. It doesn't account for the time taken to run the code, but it does give you an idea of the relative rendering times.

By using such a testing scheme, you can get impartial data with regard to system performance. This is much more reliable than asking beta testers whether an animation was fast or slow. You can accumulate data on a variety of machines, especially the low end of your target machines, to evaluate the appropriate trade-offs between appearance and performance. You'll often find that minor differences in visual appearance (hardly apparent to users) result in measurable improvements in runtime performance.

Final Thoughts

The benchmark code offers a more realistic evaluation of performance than relying on the general optimization rules alone. It also helps you evaluate the trade-offs between techniques that conserve or consume processor power. For example, a complex shape containing many points may animate faster than a larger, simple circle. Furthermore, a solid shape moving in front of a bitmap may cause a bigger performance hit than a movie clip with transparency that is moving over a much simpler background.

Using code to benchmark your optimizations gives you the best idea of what has the most impact on performance for your particular animation. This type of benchmarking is best for comparing techniques to see which is relatively faster, not to see how fast an animation or application runs in real life [Hack #70], which depends heavily on the end user's computer and processing load.