ホーム >> 左脳Script >> Adobe Flash >> Action Script >> Object と キャスト

Object と キャスト


AVM(Action Script 仮想マシン)上で動くオリジナル仮想マシンを作る場合、変数を何らかの配列なりに格納する必要があります。

そこで変数をなんらかの配列で管理しようという事になる訳です。
  • Object:連想記憶配列。すべてを名前で管理できるので、とてもとても楽。VMを作るのは。
  • Array:つまるところ、添え字に整数を使うことを前提とした、便利メソッドが追加された Object クラス。特に速度が優れているとかは無い。ハズ。
  • Vector:添え字を整数に限定、格納するデータの型を予め設定し変更できない、という制約が在るが、この制約の為に、上記2つのクラスより早い。 沢山の要素にアクセスしなければならない用途を想定しているようだ。

Vector が整数インデックスで早いのは判りますが、要素の型を指定するのは、具体的にどんな影響があるのでしょうか。


いきなりベンチマーク

検証コード。

{
    var ary:Vector.<Object> = new Vector.<Object>();
    var aryi:Vector.<int> = new Vector.<int>();
    var aryn:Vector.<Number> = new Vector.<Number>();
    var aryx:Vector.<*> = new Vector.<*>();
    var i:int;
    for (i = 0; i < 100000; i++)
    {
        ary.push(i);
        aryi.push(i);
        aryn.push(i);
        aryx.push(i);
    }

    function test0():void 
    {
        var sum:Number = 0;
        for (var i:int = 0; i < 100000; i++)
        {
            sum = sum + ary[i];
        }
    }
    function test1():void 
    {
        var sum:Number = 0;
        for (var i:int = 0; i < 100000; i++)
        {
            sum = sum + aryn[i];
        }
    }
    function test2():void 
    {
        var sum:Number = 0;
        for (var i:int = 0; i < 100000; i++)
        {
            sum = sum + Number(ary[i]);
        }
    }
    function test3():void 
    {
        var sum:Number = 0;
        for (var i:int = 0; i < 100000; i++)
        {
            sum = sum + aryi[i];
        }
    }
    function test4():void 
    {
        var sum:int = 0;
        for (var i:int = 0; i < 100000; i++)
        {
            sum = sum + int(ary[i]);
        }
    }
    function test5():void 
    {
        var sum:Number = 0;
        for (var i:int = 0; i < 100000; i++)
        {
            sum = sum + (ary[i] as Number);
        }
    }
    function test6():void 
    {
        var sum:Number = 0;
        for (var i:int = 0; i < 100000; i++)
        {
            sum = sum + aryx[i];
        }
    }

    trace(getTerm(test0));
    trace(getTerm(test1));
    trace(getTerm(test2));
    trace(getTerm(test3));
    trace(getTerm(test4));
    trace(getTerm(test5));
    trace(getTerm(test6));
}

public static function getTerm(f:Function):Number 
{
    var av:Number = 0;
    for (var i:int = 0; i < 10; i++)
    {
        var st:int = getTimer();
        f();
        var tim:int = getTimer() - st;
        av += tim;
    }
    return  av / 10;
}

私の環境では、以下のような結果になりました。絶対値はあくまで目安です。

60.3
21.7
21.5
21.1
21.3
69.7
59


  • 一番上の「sum = sum + ary[i];」は要素の型をキャストしていないので、演算実行時に型の評価を行っているようです。特に"+"演算子は、数値の加算の他に、文字列の連結も可能ですので、要素となる Object が具体的にどんな型なのか真面目にチェックしなければなりません。そのため、キャストを使わない場合に比べ、3倍程度の時間がかかっています。

    "+" が駄目なら、と"-"に変更したところ、コンパイルの段階で型のエラーが出ました。"+"演算子で試験した事自体あまり良くなかったようです。他の演算子では、Object から明示的なキャストが必須です。

  • Vector で要素の型を指定するパターンと、要素の型を Object のまま、演算時にキャストするパターンで、あまりに差がありません。また、int と Number の差は、この検証コードでは測れないほど微小?なようです。

  • 「as」でキャストするパターンが実は最も重く、型変換できなかった時の処理、と言うより型変換ができるかどうかの判別に処理が割かれているようです。最後の「要素の型に * を使う」パターンも、処理自体は Object と同じ程度の時間がかかっています。


  • 個人的結論

    変数の管理は「Vector.<Object>」で、実用レベルと判断しました。
    • 要素の型を Object にし、演算時にキャストするのが最も簡単なようだ。
    • キャストに「as」は使うな。

    要素の型をがっちり決めても、AVM 上で動く VM の仕組みを想定すると、労力に見合わない無駄な手間となってしまうでしょう。






トラックバック(0)

トラックバックURL: http://n-yagi.0r2.net/sanoupulurun/mt-tb.cgi/273

コメントする

ホーム >> 左脳Script >> Adobe Flash >> Action Script >> Object と キャスト

アーカイブ

このブログ記事について

このページは、n-yagiが2010年8月29日 15:01に書いたブログ記事です。

ひとつ前のブログ記事は「もチャット作成日誌:2010年7月10日」です。

次のブログ記事は「もチャット作成日誌:2010年7月11日~12日」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

Creative Commons License
このブログはクリエイティブ・コモンズでライセンスされています。