Skip to content

Instantly share code, notes, and snippets.

@tschneidereit
Created April 19, 2010 16:31
Show Gist options
  • Save tschneidereit/371242 to your computer and use it in GitHub Desktop.
Save tschneidereit/371242 to your computer and use it in GitHub Desktop.
Benchmarks for various forms of listeners for ADDED_TO_STAGE and REMOVED_FROM_STAGE
package
{
import com.gskinner.performance.TestSuite;
import com.gskinner.performance.ptest;
import flash.display.DisplayObjectContainer;
import flash.display.Sprite;
import flash.events.Event;
import flash.text.TextField;
import flash.utils.getQualifiedClassName;
/**
* Tests the performance impact of various forms of listening to ADDED_TO_STAGE and REMOVED_FROM_STAGE
*
* Results for release build running in FP 10.0.42.34 on a 2009 MacBook Pro 2.8 GHz Core 2 Duo:
* [MethodTest name='no listeners' time=92.7 min=79 max=113 deviation=0.367 memory=5098]
* [MethodTest name='emtpy added listener' time=173.3 min=172 max=175 deviation=0.017 memory=5333]
* [MethodTest name='emtpy removed listener' time=152.0 min=152 max=152 deviation=0.000 memory=5325]
* [MethodTest name='emtpy removed listener, without capturing' time=125.0 min=124 max=126 deviation=0.016 memory=5245]
* [MethodTest name='emtpy added and removed listeners' time=242.7 min=242 max=243 deviation=0.004 memory=5638]
* [MethodTest name='two emtpy added and removed listeners' time=289.7 min=288 max=292 deviation=0.014 memory=5637]
* [MethodTest name='get FQCN in added and removed listeners' time=252.0 min=252 max=252 deviation=0.000 memory=5636]
* [MethodTest name='Full management for multiple listeners' time=282.3 min=259 max=304 deviation=0.159 memory=5664]
*
* Relevant times are the "min" value. Times extremely stable over runs, nearly identical between debug and release player.
*/
public class StageListenersTests extends Sprite
{
private var m_out:TextField;
public function StageListenersTests()
{
super();
if (!stage)
{
addEventListener(Event.ADDED_TO_STAGE, startTests);
}
else
{
startTests();
}
}
protected function startTests(event : Event = null) : void
{
removeEventListener(Event.ADDED_TO_STAGE, startTests);
m_out = new TextField();
m_out.width = stage.stageWidth;
m_out.autoSize = 'left';
addChild(m_out);
var loops:int = 1000;
out(ptest(testListeners, [loops], 'no listeners', 3));
out(ptest(testListeners, [loops, emptyListener], 'emtpy added listener', 3));
out(ptest(testListeners, [loops, null, emptyListener], 'emtpy removed listener', 3));
out(ptest(testListeners, [loops, null, emptyListener, false], 'emtpy removed listener, without capturing', 3));
out(ptest(testListeners, [loops, emptyListener, emptyListener], 'emtpy added and removed listeners', 3));
out(ptest(testDoubleListeners, [loops, emptyListener, emptyListener], 'two emtpy added and removed listeners', 3));
out(ptest(testListeners, [loops, getFQCNListener, getFQCNListener], 'get FQCN in added and removed listeners', 3));
out(ptest(testInterfaceListeners, [loops], 'Full management for multiple listeners', 3));
}
protected function out(str:*):void {
m_out.appendText(str + '\n');
}
protected function handleTestComplete(evt:Event):void {
var test:TestSuite = evt.target as TestSuite;
trace(test.toXML().toXMLString());
}
protected function testListeners(count : int, addedListener : Function = null, removedListener : Function = null, useCapture : Boolean = true) : void
{
if (addedListener != null) stage.addEventListener(Event.ADDED_TO_STAGE, addedListener, useCapture);
if (removedListener != null) stage.addEventListener(Event.REMOVED_FROM_STAGE, removedListener, useCapture);
for (var i : int = count; i--;)
{
var previousItem : DisplayObjectContainer = stage;
var item : DisplayObjectContainer;
for (var j : int = 10; j--;)
{
item = new Sprite();
previousItem.addChild(item);
previousItem = item;
}
for (j = 10; j--;)
{
var parent : DisplayObjectContainer = item.parent;
parent.removeChild(item);
item = parent;
}
}
if (addedListener != null) stage.removeEventListener(Event.ADDED_TO_STAGE, addedListener, true);
if (removedListener != null) stage.removeEventListener(Event.REMOVED_FROM_STAGE, removedListener, true);
}
private function testDoubleListeners(count : int, addedListener : Function = null, removedListener : Function = null) : void
{
stage.addEventListener(Event.ADDED_TO_STAGE, emptyListener2, true);
stage.addEventListener(Event.REMOVED_FROM_STAGE, emptyListener2, true);
testListeners(count, addedListener, removedListener);
stage.removeEventListener(Event.ADDED_TO_STAGE, emptyListener2, true);
stage.removeEventListener(Event.REMOVED_FROM_STAGE, emptyListener2, true);
}
protected function testInterfaceListeners(count : int) : void
{
var handler : Handler = new Handler(stage);
for (var i : int = count; i--;)
{
var previousItem : DisplayObjectContainer = stage;
var item : DisplayObjectContainer;
for (var j : int = 10; j--;)
{
item = new Sprite();
previousItem.addChild(item);
previousItem = item;
}
for (j = 10; j--;)
{
var parent : DisplayObjectContainer = item.parent;
parent.removeChild(item);
item = parent;
}
}
handler.removeListeners();
}
//various listeners to test
private function emptyListener(event : Event) : void
{
}
private function emptyListener2(event : Event) : void
{
}
private function getFQCNListener(event : Event) : void
{
var fqcn : String = getQualifiedClassName(event.target);
}
private function getInterfaceListener(event : Event) : void
{
var fqcn : String = getQualifiedClassName(event.target);
}
}
}
import flash.display.DisplayObject;
import flash.display.DisplayObjectContainer;
import flash.events.Event;
import flash.utils.getQualifiedClassName;
class Handler
{
private var m_view:DisplayObjectContainer;
private var m_firstListener:IListener;
public function Handler(view : DisplayObjectContainer) : void
{
m_view = view;
setupListeners();
m_view.addEventListener(Event.ADDED_TO_STAGE, addedListener, true);
m_view.addEventListener(Event.REMOVED_FROM_STAGE, removedListener, true);
}
private function setupListeners():void
{
m_firstListener = new Listener();
m_firstListener.next = new Listener();
m_firstListener.next.next = new ModuleListener();
}
public function removeListeners() : void
{
m_view.removeEventListener(Event.ADDED_TO_STAGE, addedListener, true);
m_view.removeEventListener(Event.REMOVED_FROM_STAGE, addedListener, true);
}
private function addedListener(event : Event) : void
{
var listener : IListener = m_firstListener;
var view : DisplayObject = DisplayObject(event.target);
var className : String = getQualifiedClassName(view);
while (listener)
{
listener.handleView(view, className);
listener = listener.next;
}
}
private function removedListener(event : Event) : void
{
}
}
interface IListener
{
function get hasNext() : Boolean;
function get next() : IListener;
function set next(next : IListener) : void;
function handleView(view : DisplayObject, className : String) : void;
}
class Listener implements IListener
{
private var m_next:IListener;
public function get hasNext():Boolean
{
return m_next != null;
}
public function get next():IListener
{
return m_next;
}
public function set next(next:IListener):void
{
m_next = next;
}
public function handleView(view:DisplayObject, className:String):void
{
//do something with the view
}
}
class ModuleListener extends Listener
{
override public function handleView(view:DisplayObject, className:String):void
{
if (view is IListener)
{
//do something else
}
else
{
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment