7

これは、ある意味で、私の前の質問へのフォローアップです。

RGBピクセル値の 1 次元配列を取得するさまざまな方法を比較する jsPerfを作成しました

var rgb = [R, G, B, R, G, B...]

そして、それらを HTML5 キャンバスのRGBA値に変換します (アルファ チャネルは常に 255で、完全に不透明です)。

var rgba = [R, G, B, 255, R, G, B, 255...]

私のテストでは、「For ループ」という名前のテストしたループの 1 つが、他のループよりも天文学的に遅いことがわかりました。他のループが1 秒間に数億回も処理を完了していたのに対し、1 秒間になんと 86 回も実行されました。ループは上記の jsPerf リンクにありますが、ここに「For ループ」と「4*unrolled、アルファをスキップ」を含むコードが少しあります。これは、テストで高速なループの 1 つです。

//Setup for each test
function newFilledArray(length, val) {
    var array = Array(length);
    for (var i = 0; i < length; i++) {
        array[i] = val;
    }
    return array;
}

var w = 160;  //width
var h = 144;  //height

var n = 4 * w * h; //number of length of RGBA arrays
var s = 0, d = 0;  //s is the source array index, d is the destination array index

var rgba_filled = newFilledArray(w*h*4, 255);  //an RGBA array to be written to a canvas, prefilled with 255's (so writing to the alpha channel can be skipped
var rgb = newFilledArray(w*h*3, 128);  //our source RGB array (from an emulator's internal framebuffer)

//4*unrolled, skip alpha - loop completes (exits) 185,693,068 times per second
while (d < n) {
    rgba_filled[d++] = rgb[s++];
    rgba_filled[d++] = rgb[s++];
    rgba_filled[d++] = rgb[s++];
    d++;
}

//For Loop - loop completes (exits) 85.87 times per second
for (var d = 0; d < n; ++d) {
    rgba_filled[d++] = rgb[s++];
    rgba_filled[d++] = rgb[s++];
    rgba_filled[d++] = rgb[s++];
}

構文が信じられないほど似ているのに、パフォーマンスの点でこれほど離れているのはどうしてでしょうか?

4

1 に答える 1

10

ループだけforが非常に遅い理由は、それが唯一の正しいテスト ケースだからです。他のすべてのテストケースは、特に の値をリセットすることはdありません。したがって、最初の反復は正常で、残りは明らかに超高速です:)

このjsperfはより良い結果をもたらします。これにより、for ループは最速の結果よりわずかに遅くなります。

アップデート

bfavarettoが示唆したようsに、より一貫した結果を得るには、構築しているターゲット配列もリセットする必要があります。彼の結果はここにあります。

于 2013-07-09T03:35:22.083 に答える