在某种程度上,这是我previous question的后续行动。
我创建了a jsPerf,它比较了采用 RGB 像素值的1维数组的多种方法
var rgb = [R, G, B, R, G, B...]
并将这些值转换为HTML5画布的 RGBA 值(其中Alpha通道始终为255 ,完全不透明)。
var rgba = [R, G, B, 255, R, G, B, 255...]
在我的测试中,我发现我测试过的一个循环,名为" For Loop",在天文学上比其他循环慢。当其他循环完成每秒数亿次的操作时,它以高达每秒86次进行加权。循环可以在上面的jsPerf链接中找到,但这里有一些代码,其中包含" For Loop"并且" 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++];
}
如何在语法上如此惊人地相似,但在性能方面却如此遥远?
答案 0 :(得分:10)
只有for
循环这么慢的原因是因为它是唯一正确的测试用例;所有其他测试用例从不重置,其中包括d
的值,所以第一次迭代是正常的,其余的显然非常快:)
这个jsperf给出了更好的结果,因为for循环只比最快的结果稍慢。
<强>更新强>
根据bfavaretto建议,您还应重置s
以及您正在构建的目标数组,以获得更一致的结果。他的结果可以找到here。