2011年1月6日 星期四

Flex 程式效能簡易測試工具

最近離職後開始在整理自已做測試的小東西,因此順便把測試結果簡單重整成一個工具類,以下是一個簡單的程式執行效能測試類,不夠好或考量不夠的地方請大家多多指教~


//interface
package com.utils
{
 public interface ILoopTestTools
 {
  function startExecuteTestFunction():void
  function set testFunctionA(functin:Function):void;
  function set testFunctionB(functin:Function):void;
 }
}
//Class
package com.utils
{
 import flash.display.DisplayObject;
 import flash.events.IEventDispatcher;
 import flash.events.MouseEvent;
 import flash.utils.Timer;
 import flash.utils.getTimer;

 import mx.controls.TextArea;
 import mx.core.IButton;
 import mx.managers.IBrowserManager;

 public class LoopTestTools implements ILoopTestTools
 {
  private var _averageStoreA:Vector.<number>;
  private var _averageStoreB:Vector.<number>;
  private var _canExecute:Boolean = true;

  public function LoopTestTools(varifyCount:int=10 , count:int=10000)
  {
   super();
   this.verifyCount = varifyCount;
   this.runCount = count;
   init();
  }

  protected function init():void
  {
   setDefaultReportMethod();
   initVector();
  }
  
  protected function setDefaultReportMethod():void
  {
   reportMethdo = function(target:TextArea , executeTime:Number):void
   {
    target.text += "運算圈數:" + _runCount + '\n';
    target.text += "運算時間:" + executeTime + "毫秒" + '\n';
    target.text += "---------------------------------" + '\n';
   }
   reportAvgMethod = function(target:TextArea , averageTime:Number):void
   {
    target.text += "平均時間:" + averageTime + "毫秒" + '\n';
    target.text += "---------------------------------" + '\n';
   }
  }
  private function initVector():void
  {
   initStoreA();
   initStoreB();
  }

  private function initStoreA():void
  {
   _averageStoreA = new Vector.<number>;
  }

  private function initStoreB():void
  {
   _averageStoreB = new Vector.<number>;
  }

  private function checkStoreNeedInit():void
  {
   if(_averageStoreA != null && _averageStoreA.length > 0)
    initStoreA();
   if(_averageStoreB != null && _averageStoreB.length > 0)
    initStoreB();
  }

  //驗證次數,以1開始計算
  private var _verifyCount:int;
  public function get verifyCount():int
  {
   return _verifyCount;
  }
  public function set verifyCount(value:int):void
  {
   if(_verifyCount != value)
   {
    _verifyCount = value;
    checkStoreNeedInit();
   }
  }

  private var _runCount:int;
  /**對一個function做重複運算的次數,從一開始*/
  public function get runCount():int
  {
   return _runCount;
  }
  public function set runCount(count:int):void
  {
   if(_runCount != count)
   {
    _runCount = count;
    checkStoreNeedInit();
   }
  }

  public function startExecuteTestFunction():void
  {
   if(_canExecute == true)
   {
     _canExecute = false;
     clearBoard();
     var i:int=0;
     for( i ; i < verifyCount ; i ++)
     {
      _averageStoreA[i] = executeTestFunction(_boardA , testFunctionA);
       _averageStoreB[i] = executeTestFunction(_boardB , _testFunctionB);
     }
      reportAvgMethod(_boardA , getAverageTime(_averageStoreA));
      reportAvgMethod(_boardB , getAverageTime(_averageStoreB));
     _canExecute = true;
   }
   }

  private function clearBoard():void
  {
   if(_boardA != null)
     _boardA.text = "";
   if(_boardB != null)
     _boardB.text = "";
  }
  
   private function executeTestFunction(target:TextArea , method:Function):Number
   {
    var _beforTime:Number=0;
    var _afterTime:Number=0;
    var _executeTime:Number;
    var testCount:int = 0;
    _beforTime = getTimer();
    for( testCount ; testCount < runCount ; testCount++)
    {
      method();
    }
     _afterTime = getTimer();
    _executeTime = (_afterTime - _beforTime);
     reportMethdo(target , _executeTime);
    return _executeTime;
   }
   private function getAverageTime(tarage:Vector.):Number
  {
   var avgTime:Number = 0;
   var i:int = 0;
   for(i = 0 ; i < tarage.length ; i++)
   {
    avgTime += tarage[i];
   }
   return avgTime /= tarage.length;
  }

  private var _testFunctionA:Function;
  /**要做迴圈測試的Function A*/
  public function set testFunctionA(method:Function):void
  {
    if(_testFunctionA != method)
    {
     _testFunctionA = method;
    }
  }

  private var _testFunctionB:Function;
  /**要做迴圈測試的Function B*/
  public function set testFunctionB(method:Function):void
  {
    if(_testFunctionB != method)
    {
     _testFunctionB = method;
    }
  }

  private var _boardA:TextArea;
  public function set boardA(obj:TextArea):void
  {
    if(_boardA != obj)
    {
     _boardA = obj;
    }
  }

  private var _boardB:TextArea;
  public function set boardB(obj:TextArea):void
  {
    if(_boardB != obj)
    {
     _boardB = obj;
    }
  }

  private var _startButton:DisplayObject;
  public function set startButton(obj:DisplayObject):void
  {
    if(_startButton != obj)
    {
     removeListener(_startButton)
     _startButton = obj;
     addListener(_startButton);
    }
  }

  private function onDwonHandle(e:MouseEvent):void
  {
    startExecuteTestFunction();
  }
  //
  //
  //
  private var _reportMethod:Function;
  public function get reportMethdo():Function
  {
    return _reportMethod;
  }
  public function set reportMethdo(method:Function):void
  {
    if(_reportMethod != method)
    {
     _reportMethod = method;
    }
  }

  private var _reportAvgMethod:Function;
  public function get reportAvgMethod():Function
  {
    return _reportAvgMethod;
  }
  public function set reportAvgMethod(method:Function):void
  {
    if(_reportAvgMethod != method)
    {
     _reportAvgMethod = method;
    }
  }
  //-------------------------
  // Listener Proxy method
  //-------------------------
  private function addListener(obj:IEventDispatcher):void
  {
    if(obj != null)
    {
     obj.addEventListener(MouseEvent.MOUSE_DOWN , onDwonHandle);
    }
  }
  private function removeListener(obj:IEventDispatcher):void
  {
    if(obj != null)
    {
     obj.removeEventListener(MouseEvent.MOUSE_DOWN , onDwonHandle);
    }
  }

 }
}

//mxmlPage
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"  minWidth="955" minHeight="600" applicationComplete="application1_applicationCompleteHandler(event)"
>
 <mx:Script>
  <![DATA[
   import com.utils.LoopTestTools;
   import mx.events.FlexEvent;
   private var _loopTestTools:LoopTestTools;
   protected function application1_applicationCompleteHandler(event:FlexEvent):void
   {
     testA();
     //testB();
   }
   
   private function testA():void
   {
    //輸出十筆測驗,每次測驗跑十萬圈
    _loopTestTools = new LoopTestTools(10,100000);
    _loopTestTools.boardA = _textAreaA;
    _loopTestTools.boardB = _textAreaB;
    _loopTestTools.startButton = _startBtn;
    _loopTestTools.testFunctionA = usingMathAbs;
    _loopTestTools.testFunctionB = usingUserAbs;
   }

   private function testB():void
   {
    //輸出十筆測驗,每次測驗跑十萬圈
    _loopTestTools = new LoopTestTools(10,1);
    _loopTestTools.boardA = _textAreaA;
    _loopTestTools.boardB = _textAreaB;
    _loopTestTools.startButton = _startBtn;
    _loopTestTools.testFunctionA = ifAndElse;
    _loopTestTools.testFunctionB = threeOperator;
   }
   public function usingMathAbs():void
   {
    var n:Number = Math.abs(-1);
   }

   public function usingUserAbs():void
   {
    var n:Number = (-1>0)?1:-1;
   }
  
   //--------------------------------------
   // 運算圈數由外在 method自行控制
   //--------------------------------------
   public function ifAndElse():void
   {
    var _value:int;
    var _k:int=0;
    for( _k ; _k < 100000 ; _k++)
    {
     if( (_k % 2)==0)
     {
      _value = 0;
     }
     else
     {
      _value = 1;

     }
    }
   }

   public function threeOperator():void
   {
    var _value:int;
    var k1:int=0;
    for(k1 ; k1 < 100000 ; k1++)
    {
     ((k1 % 2)==0)? _value=0 :_value=1;
    }
   }
  ]]>
 </mx:Script>
  <mx:HBox>
  <mx:VBox>
    <mx:Panel title="if else 運算速度" width="300" height="520">
     <mx:TextArea id="_textAreaA" editable="false" width="100%" height="100%"/>
    </mx:Panel>
  </mx:VBox>
  <mx:VBox>
  <mx:Panel title="三元運算子 運算速度" width="300" height="520">
    <mx:TextArea id="_textAreaB" editable="false" width="100%" height="100%"/>
  </mx:Panel>
  </mx:VBox>
  <mx:Button id="_startBtn" label="開始運算"/>
 </mx:HBox>
</mx:Application>

沒有留言:

張貼留言