Created
April 19, 2010 16:31
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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