在对Array.prototype.fill()
方法进行一些测试(Chrome on macOS)时,它显然几乎是创建自己的for
循环并填充数组的两倍慢(如果不慢)。 / p>
显然做了类似的事情:
for( var i = 0; i < Array.length; i++) {
A[i] = 0;
}
VS
Array.fill(0);
Array.fill()
方法需要大约210-250ms来填充大小为10000000的数组,而for
循环需要大约70-90ms。似乎可以重写Array.fill()
方法来简单地使用直接循环,因为您始终知道您的初始索引和目标索引。
let arrayTest = new Array(10000000),
startTime,
endTime;
startTime = performance.now();
arrayTest.fill(0);
endTime = performance.now();
console.log("%sms", endTime - startTime);
arrayTest = new Array(10000000);
startTime = performance.now();
for (let i = 0; i < arrayTest.length; i++){
arrayTest[i] = 0;
}
endTime = performance.now();
console.log("%sms", endTime - startTime);
&#13;
与我在当地测试时相比,上述实际上显示出更大的差异。
编辑:我在进一步测试后意识到,当切换到Firefox及其真正依赖引擎时,差异会大大减少。我猜这主要是因为不同的JavaScript引擎优化循环与方法的结果。看起来好像Array.prototype.fill()
中的循环可以优化以解决这个差异。
答案 0 :(得分:1)
结果与使用JavaScript编写部分Chrome的报告一致,并依赖于运行时分析和优化来提高性能。
我将测试代码打包在一个要从测试页面重复调用的函数中,该测试页面可以加载到不同的浏览器中(这不是一个可运行的代码段):
<!DOCTYPE html>
<html><head><meta charset="utf-8">
<title>Array.prototype.fill</title>
<script>
Array.prototype.customFill = function( value, start = 0, end = this.length) {
var count = end-start;
if( count > 0 && count === Math.floor(count)){
while( count--)
this[start++]=value;
}
return this;
}
function test() {
let arrayTest,
startTime,
endTime,
arraySize = 1000000;
arrayTest = new Array(arraySize);
startTime = performance.now();
for (let i = 0; i < arrayTest.length; i++){
arrayTest[i] = 0;
}
endTime = performance.now();
console.log("%sms (loop)", endTime - startTime);
arrayTest = new Array(arraySize);
startTime = performance.now();
arrayTest.fill(0);
endTime = performance.now();
console.log("%sms (fill)", endTime - startTime);
arrayTest = new Array(arraySize);
startTime = performance.now();
arrayTest.customFill(0);
endTime = performance.now();
console.log("%sms (custom fill)", endTime - startTime);
}
</script>
</head>
<body>
open the console and click <button type="button" onclick="test()">test</button>
</body>
</html>
可以调整阵列大小以适应所用设备的性能。
Windows下的Chrome搜索结果显示该循环获得了巨大的性能,用于测试的前两次测试点击。在第二次点击时,循环的时间似乎有所改善。在第三次单击时,循环和填充方法似乎都被优化并以几乎相同且改进的速度运行。重新加载页面后,结果可重复。
我发现这与Chrome脚本优化策略一致,与使用C ++或类似内容编写的Chrome Array.prototype.fill
不一致。虽然Array.prototype.fill.toString()
将函数体报告为“本机代码”,但并未说明它所使用的语言。
为自定义填充方法添加了时间,为速度编写,并存储为Array.prototype.customFill
。
Firefox的Timings与用脚本编写的Array.prototype.fill
一致。本机实现优于循环,并且通常(但不总是)比自定义填充方法更快。
Chrome show的Timings也与Array.prototype.fill
在某种优化的脚本中编写一致。测试的所有三种填充方法显示在一次或两次测试点击后速度增加。
但是,自定义填充方法的启动速度比Chromes原生版快十倍。您需要在自定义方法中放入无意义的代码,以便将其减慢到足以接近本机方法的初始速度。相反,在优化之后,本机方法的速度快了两倍 - 用JavaScript编写的自定义方法永远不会在相同的范围内进行优化。
虽然Chromes Array.prototype.fill
方法可以用JavaScript编写,但似乎需要额外的解释来解释最初的缓慢和最终性能优化。
答案 1 :(得分:1)
此JSPerf确认填充比for循环慢。