Ein kleiner Vergleich bringt es ans Licht: die Funktionalität von Math.abs() kann in AS3 durch eigene Funktionen deutlich schneller realisiert werden. Dazu habe ich eine kleine Testklasse geschrieben, die verschiedene Methoden vergleicht:
package de.sb12.matthias.playground.mathabs { import flash.display.Sprite; import flash.text.TextField; import flash.text.TextFieldAutoSize; import flash.utils.getTimer; /** * creation date: 07.08.2009 * @author Matthias Dehmel * * modified by $Author$ on $Date$ * @version $Id$ */ public class MathAbsPerformance extends Sprite { private const TESTRUNS : uint = 200000; private var _log : TextField; public function MathAbsPerformance() { _log = new TextField( ); _log.width = 500; _log.autoSize = TextFieldAutoSize.LEFT; _log.wordWrap = true; _log.multiline = true; _log.x = _log.y = 20; addChild(_log); mathAbs(); manualMathAbs(); inlineManualMathAbs(); bitshift(); } private function mathAbs() : void { var start : Number = getTimer(); var num : Number; var i : int = 0; for (i; i < TESTRUNS ; i++) num = Math.abs( 5 ); log('Math.abs', getTimer( ) - start ); } private function manualMathAbs() : void { var start : Number = getTimer(); var num : Number; var i : int = 0; for (i; i < TESTRUNS ; i++) num = abs( 5 ); log('manual abs', getTimer( ) - start ); } private function abs( value : Number ) : Number { return ( value < 0 ) ? -value : value; } private function inlineManualMathAbs() : void { var start : Number = getTimer(); var num : Number = 5; var i : int = 0; for (i; i < TESTRUNS ; i++) num = ( num < 0 ) ? -num : num; log('manual inline abs', getTimer( ) - start ); } private function bitshift() : void { var start : Number = getTimer(); var num : Number = 5; var i : int = 0; for (i; i < TESTRUNS ; i++) num = ( num^( num >> 31 ) ) - ( num >> 31 ); log('bitshift', getTimer( ) - start ); } private function log( type : String, time : uint ) : void { _log.appendText( '\n' + type + ': ' + time.toString() + 'ms' ); } } }
Folgende verschiedene Möglichkeiten habe ich getestet:
1. Math.abs(): Der normale Aufruf über die mitgelieferte Math-Klasse
2. eigene abs()-Funktion: stellt die gleiche Funktionalität wie Math.abs() bereit
3. eigene abs()-Funktion als inline code: dasselbe wie unter 2., nur dass keine extra Funktion aufgerufen wird
4. Bitshift-Operation: stellt die gleiche Funktionalität wie Math.abs() bereit
Folgende Ergebnisse habe ich dabei erzielt (200.000 Durchläufe):
1. Math.abs(): 23ms
2. eigene abs()-Funktion: 18ms
3. eigene abs()-Funktion als inline code: 1ms
4. Bitshift-Operation: 2ms
Wenn es also um zeitkritische Berechnungen geht, würde ich immer dazu raten in der relevanten Funktion eine eigene Math.abs()-Implementierung als inline code zu integrieren,da diese mitunter ~23x schneller ist als die Flash-interne Implementierung.
Kommentar schreiben