今このタイミングでFlash9のArrayの挙動については100%誰も興味が無い.


id:keim_at_Si:20080523の続き.as3のArrayはかなり気持ち悪いので,自分のプログラムでも,ボトルネックになりそうなところではほとんど使ってません.Flash10のVector調べる前にArrayの気持ち悪さを再確認してみましょう.しかし,ほんとキモいなー,これ.


Array ベンチマーク for int
Array ベンチマーク for Number
少し止まったあと,各ループの処理時間が表示されます.環境依存激しそうなので皆さん自分の環境でやってみてください.プレイヤーが古いですがうちの1GHzノートの場合,


for int

デバッガの結果.
Windows XP/StandAlone/WIN 9,0,115,0/debugger
862[ms] { array[i] += t1; }
846[ms] { array[i] = array[i] + t1; }
1047[ms] { array[i] = int(array[i]) + t1; }
494[ms] { t0 = array[i]; t0 += t1; array[i] = t0; }
491[ms] { t0 = array[i]; t0 = t0 + t1; array[i] = t0; }
583[ms] { t0 = array[i]; array[i] = t0 + t1; }
685[ms] { array[i] = array[i + t1]; }
417[ms] { t0 = i + t1; array[i] = array[t0]; }
ie上での結果.
Windows XP/ActiveX/WIN 9,0,115,0/normal
695[ms] { array[i] += t1; }
698[ms] { array[i] = array[i] + t1; }
451[ms] { array[i] = int(array[i]) + t1; }
376[ms] { t0 = array[i]; t0 += t1; array[i] = t0; }
374[ms] { t0 = array[i]; t0 = t0 + t1; array[i] = t0; }
449[ms] { t0 = array[i]; array[i] = t0 + t1; }
529[ms] { array[i] = array[i + t1]; }
321[ms] { t0 = i + t1; array[i] = array[t0]; }


for Number

デバッガの結果.
Windows XP/StandAlone/WIN 9,0,115,0/debugger
919[ms] { array[i] += t1; }
932[ms] { array[i] = array[i] + t1; }
1080[ms] { array[i] = Number(array[i]) + t1; }
604[ms] { t0 = array[i]; t0 += t1; array[i] = t0; }
613[ms] { t0 = array[i]; t0 = t0 + t1; array[i] = t0; }
644[ms] { t0 = array[i]; array[i] = t0 + t1; }
ie上での結果.
Windows XP/ActiveX/WIN 9,0,115,0/normal
769[ms] { array[i] += t1; }
770[ms] { array[i] = array[i] + t1; }
502[ms] { array[i] = Number(array[i]) + t1; }
505[ms] { t0 = array[i]; t0 += t1; array[i] = t0; }
508[ms] { t0 = array[i]; t0 = t0 + t1; array[i] = t0; }
512[ms] { t0 = array[i]; array[i] = t0 + t1; }


4,5,6行目の高速化も十分気持ち悪いんだけど,特にArrayの異常さを感じたのは for int の7,8行目かな.だれかTamarinソースによる合理的な説明を求む.あと3行目のデバッガとブラウザでの速度差に震撼.キャストしておくとJITコンパイラで最適化されるよって話を,たしかAdobeのプレゼン資料で読んだ気はしてたんだけど,デバッガ上では最適化されてないみたい.うわー.


とりあえずArrayは計算式内で直接使わずローカル変数に代入して使う.あとインデックスもあらかじめ計算しておく.
結論,Arrayきもい.


以下ソース
for int.

package {
    import flash.text.TextField;
    import flash.display.*;
    import flash.utils.getTimer;
    import flash.system.Capabilities;
    
    
    [SWF(width="640", height="480", backgroundColor='#ffffff')]
    public class main extends Sprite
    {
        function main()
        {
            var i:int, imax:int = 4999999;
            var time:int, array:Array = new Array(imax);

            var res:String = Capabilities.os+"/";
            res += Capabilities.playerType+"/";
            res += Capabilities.version+"/";
            res += (Capabilities.isDebugger?"debugger":"normal")+"\n";

            
        //----test start
            var t0:int, t1:int;
            
            for (i=0; i<imax; i++) { array[i] = int(0); }
            imax--;

            t1 = 1;
            time = getTimer();
            for (i=0; i<imax; i++) { array[i] += t1; }
            res += String(getTimer() - time) + '[ms] { array[i] += t1; }\n';

            time = getTimer();
            for (i=0; i<imax; i++) { array[i] = array[i] + t1; }
            res += String(getTimer() - time) + '[ms] { array[i] = array[i] + t1; }\n';

            time = getTimer();
            for (i=0; i<imax; i++) { array[i] = int(array[i]) + t1; }
            res += String(getTimer() - time) + '[ms] { array[i] = int(array[i]) + t1; }\n';
            
            time = getTimer();
            for (i=0; i<imax; i++) { t0 = array[i]; t0 += t1; array[i] = t0; }
            res += String(getTimer() - time) + '[ms] { t0 = array[i]; t0 += t1; array[i] = t0; }\n';
            
            time = getTimer();
            for (i=0; i<imax; i++) { t0 = array[i]; t0 = t0 + t1; array[i] = t0; }
            res += String(getTimer() - time) + '[ms] { t0 = array[i]; t0 = t0 + t1; array[i] = t0; }\n';
            
            time = getTimer();
            for (i=0; i<imax; i++) { t0 = array[i]; array[i] = t0 + t1; }
            res += String(getTimer() - time) + '[ms] { t0 = array[i]; array[i] = t0 + t1; }\n';
            
            time = getTimer();
            for (i=0; i<imax; i++) { array[i] = array[i + t1]; }
            res += String(getTimer() - time) + '[ms] { array[i] = array[i + t1]; }\n';
            
            time = getTimer();
            for (i=0; i<imax; i++) { t0 = i + t1; array[i] = array[t0]; }
            res += String(getTimer() - time) + '[ms] { t0 = i + t1; array[i] = array[t0]; }\n';
        //----test end

            
            var tf:TextField = new TextField();
            tf.multiline = true;
            tf.width = 640;
            tf.height = 480;
            tf.selectable = true;
            tf.textColor = 0x000000;
            tf.text = res;
            addChild(tf);
            stage.scaleMode = StageScaleMode.NO_SCALE;
        }
    }
}


for Number.

        //----test start
            var t0:Number, t1:Number;

            for (i=0; i<imax; i++) { array[i] = Number(0); }
            imax--;

            t1 = 1;
            time = getTimer();
            for (i=0; i<imax; i++) { array[i] += t1; }
            res += String(getTimer() - time) + '[ms] { array[i] += t1; }\n';

            time = getTimer();
            for (i=0; i<imax; i++) { array[i] = array[i] + t1; }
            res += String(getTimer() - time) + '[ms] { array[i] = array[i] + t1; }\n';

            time = getTimer();
            for (i=0; i<imax; i++) { array[i] = Number(array[i]) + t1; }
            res += String(getTimer() - time) + '[ms] { array[i] = Number(array[i]) + t1; }\n';
            
            time = getTimer();
            for (i=0; i<imax; i++) { t0 = array[i]; t0 += t1; array[i] = t0; }
            res += String(getTimer() - time) + '[ms] { t0 = array[i]; t0 += t1; array[i] = t0; }\n';
            
            time = getTimer();
            for (i=0; i<imax; i++) { t0 = array[i]; t0 = t0 + t1; array[i] = t0; }
            res += String(getTimer() - time) + '[ms] { t0 = array[i]; t0 = t0 + t1; array[i] = t0; }\n';
            
            time = getTimer();
            for (i=0; i<imax; i++) { t0 = array[i]; array[i] = t0 + t1; }
            res += String(getTimer() - time) + '[ms] { t0 = array[i]; array[i] = t0 + t1; }\n';
        //----test end