2

私の質問を完全に定義する前に、>>この質問/回答<<は私の問題に答えないということを言わなければなりません、そして私は与えられた答えがプロパティ対の実際の効果とまったく一致しないことを自分自身に証明しました。変数またはキャッシュされたプロパティ(以下を参照)。

私はHTML5キャンバスを使用しており、640x480の領域に生のピクセルブロックを1秒間に何度も書き込みます。

.dataいくつかのチュートリアルでアドバイスされているように、変数のプロパティをキャッシュすることをお勧めしImageDataます(この場合はそうなります _SCimgData)。

そのプロパティをにキャッシュすると 、Canvasで問題なく繰り返しSC_IMG_DATA使用でき ます。putImageDataしかし、を使用して直接アクセスを繰り返すと _ScimgData.data、コードの速度低下が顕著になります(単一の640x480キャンバスを埋めるのに約1秒かかります)。

var SomeCanvas  = document.getElementById("SomeCanvas");
var SCContext   = SomeCanvas.getContext("2d");
var _SCimgData  = SomeCanvas.getImageData(0, 0, 640, 400);
var SC_IMG_DATA = _SCimgData.data;



今、私は次の疑問を持っています:

私のコードは他の種類の同様のアクセスに対しても同じくらい遅いでしょうか?

オブジェクトのいくつかの「インスタンス」(通常のユーティリティ関数によって作成される)を持つことができ、オブジェクトの配列内のインスタンスのインデックスを作成/初期化する必要がある一連の関数のオブジェクトの配列が必要です、またはそのプロパティを更新します。

私の具体的な例はこれです:

var objArray=new Array();
var objArray[0]=new Object();
    objArray[0].property1="some string property";

for(var x=0; x<65536; x++)
 doSomething(objArray[0].property1, objIDX=0);

setInterval一部のプロパティに含まれるプロパティと関数が非常に集中的に呼び出された場合(もちろん、ブラウザのロックを回避するために複数の「タイマースレッド」を使用して、1ミリ秒で数回)、そのコードはCanvasの場合と同じくらい遅くなりますか?

もしそうなら、メインオブジェクト配列内のいくつかのオブジェクトのさまざまなプロパティへのアクセスを高速化するために他にどのような選択肢がありますか?





編集1(2012-08-27)

提案をありがとう。私が取り組んでいるプロジェクトに役立つと思うので、私はそれらに賛成票を投じました。

私はメソッドの組み合わせを考えています。主にArraysの代わりにObjectsを使用して「ベースオブジェクト」の実際の配列を作成し、arr[0]文字列配列キー()の代わりに数字()で配列要素をアドレス指定しますarr["zero"]

var OBJECTS_SIZE=10
var Obj_Instances=new Array();
    Obj_Instances[0]="property or array 1 of Object 0";
    Obj_Instances[1]=new Array();
    Obj_Instances[1][0]=new ArrayBuffer(128);
    Obj_Instances[1][1]=new DataView(Obj_Instances[1][0]);
    Obj_Instances[2]="property or array 3 of Object 0";
    Obj_Instances[3]=function(){alert("some function here")};
    Obj_Instances[4]="property or array 5 of Object 0";
    Obj_Instances[5]="property or array 6 of Object 0";
    Obj_Instances[6]=3;
    Obj_Instances[7]="property or array 8 of Object 0";
    Obj_Instances[8]="property or array 9 of Object 0";
    Obj_Instances[9]="property or array 10 of Object 0";

    Obj_Instances[10]="property or array 1 of Object 1";
    Obj_Instances[11]=new Array();
    Obj_Instances[11][0]=new ArrayBuffer(128);
    Obj_Instances[11][1]=new DataView(Obj_Instances[11][0]);
    Obj_Instances[12]="property or array 3 of Object 1";
    Obj_Instances[13]=function(){alert("some function there")};
    Obj_Instances[14]="property or array 5 of Object 1";
    Obj_Instances[15]="property or array 6 of Object 1";
    Obj_Instances[16]=3;
    Obj_Instances[17]="property or array 8 of Object 1";
    Obj_Instances[18]="property or array 9 of Object 1";
    Obj_Instances[19]="property or array 10 of Object 1";

function do_Something_To_Property_Number_6(objIdx)
{
 //Fix the index to locate the base address
 //of the object instance:
 ///
   objIdx=(objIdx*OBJECTS_SIZE);
   Obj_instances[objIdx+6]++;   //Point to "Property" 6 of that object
}

たとえば、最初の10個の配列要素を占める「オブジェクト」の「インスタンス」があります。次の「インスタンス」は次の10個の配列要素を取り、以下同様に続きます(カスタム「コンストラクター」関数で初期化を作成して、配列要素の新しいブロックを追加します)。

また、jsPerfとJSHintを使用して、どちらの組み合わせがより良い結果になるかを確認します。

4

3 に答える 3

4

「疑問」に答えるには、JSPerfを使用してコードのベンチマークを行うことをお勧めします。テストしない限り、手順が他の手順よりも速いかどうかをコードだけで実際に判断することはできません。

newまた、構築中の表記ではなく、配列とオブジェクトのリテラル表記を使用することをお勧めします。

var objArray=[
    {
        property : 'some string property'
    }, {
        ...
    },
];

また、コードに基づいて、反復ごとに同じオブジェクトを使用しているため、これを使用することをお勧めします。

var obj = objArray[0].property1,
    objIDX = 0;

for(var x=0; x<65536; x++){
    doSomething(obj,objIDX);
}
于 2012-08-26T00:55:10.920 に答える
3

これはあなたの質問に完全には答えていないことを私は理解しています(すでに答えられているので)、しかしあなたは何千回も起こる関数呼び出しに関して速度の改善を探しているようです(これを見つける他の人もそうしているかもしれません)。仮定に反するので、ここにこれを含めると思いました。

関数の例:

var go = function (a,b,c,d,e,f,g,h) {
  return a+b+c+d+e+f+g+h;
}

以下は、通常、反復関数を呼び出す方法です。

var i=500000; while(i--){
  go(1,2,3,4,5,6,7,8);
}

ただし、関数のこの特定の使用法でこれらの引数のいずれも(またはいくつか)変更されない場合は、これを行う方がはるかに優れています(速度povから-明らかに非同期povではありません)

var i=500000; go.args = [1,2,3,4,5,6,7,8];
while(i--){
  go();
}

上記が機能するためには、元の関数にわずかな変更を加えるだけで済みます。

var go = function (a,b,c,d,e,f,g,h, i) {
  if ( go.args ) {
    i = go.args;
    a = i[0]; b = i[1];
    c = i[2]; d = i[3];
    e = i[4]; f = i[5];
    g = i[6]; h = i[7];
  }
  return a+b+c+d+e+f+g+h;
}

この2番目の関数は、引数を渡さないため、非常に高速に実行されます(引数なしで呼び出された関数は、非常にすばやく開始できます)。.args配列から値を取得することも、(文字列を使用しない限り)それほどコストがかかるようには見えません。1つまたは2つの引数を更新しても、それでもはるかに高速です。通常はxとyのみをシフトするため、ピクセルまたは画像データの操作に最適です。

var i=500000; go.args = [1,2,3,4,5,6,7,8];
while(i--){
  go.args[2] = i;
  go();
}

したがって、ある意味で、これはオブジェクトプロパティがローカル変数よりも高速になる可能性がある例です-少し複雑でトピックから外れている場合;)

于 2012-08-26T02:02:19.047 に答える
2

可能なブラウザの最適化にもかかわらず、オブジェクトのプロパティへのアクセスは、ローカル変数(ただし、必ずしもグローバル変数または親関数の変数である必要はありません)にアクセスするよりもコストがかかります。

プロパティが深くなるほど、パフォーマンスへの影響が大きくなります。言い換えると、

for(var x=0; x<65536; x++) 
 doSomething(objArray[0].property1, objIDX=0); 

をキャッシュobjArray[0].property1し、繰り返し割り当てないことで改善されますobjIDX

var prop = objArray[0].property1;
objIDX = 0;
for(var x=0; x<65536; x++) 
 doSomething(prop, 0); 
于 2012-08-26T00:50:40.353 に答える