异常缓慢的Javascript循环

Tre*_*own 7 javascript performance loops

在某种程度上,这是对我之前问题的后续跟进.

我创建了一个jsPerf,它比较了一些获取RGB像素值的1维数组的方法

var rgb = [R, G, B, R, G, B...]
Run Code Online (Sandbox Code Playgroud)

并将它们转换为HTML5画布的RGBA值(其中alpha通道始终为255,完全不透明).

var rgba = [R, G, B, 255, R, G, B, 255...]
Run Code Online (Sandbox Code Playgroud)

在我的测试中,我发现我测试的一个循环,标题为"For Loop",比其他循环要天文数字慢.在其他环路每秒完成数亿次操作的情况下,它以每秒高达86次的速度进行称重.循环可以在上面的jsPerf链接中找到,但这里有一些代码"For循环"和"4*展开,跳过alpha",这是测试中较快的循环之一.

//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++];
}
Run Code Online (Sandbox Code Playgroud)

如何在语法上如此惊人地相似,但在性能方面却如此遥远?

Ja͢*_*͢ck 10

只有for循环这么慢的原因是因为它是唯一正确的测试用例; 所有其他测试用例从未重置,其中包括值d,因此第一次迭代是正常的,其余的显然超级快:)

这个jsperf给出了更好的结果,因为for循环只比最快的结果稍慢.

更新

正如bfavaretto建议的那样,您还应该重置s您正在构建的目标数组以获得更一致的结果.他的结果可以在这里找到.

  • 我认为他假设在每次测试迭代之前重新运行了准备代码. (2认同)