Jam*_*hon 9 javascript performance benchmarking v8
我正在搞乱基准站点jfprefs并在http://jsperf.com/prefix-or-postfix-increment/9创建了我自己的基准测试.
基准测试是Javascript for循环的变体,使用前缀和后缀增量器以及不使用就地增量器的Crockford jslint样式.
for (var index = 0, len = data.length; index < len; ++index) {
data[index] = data[index] * 2;
}
for (var index = 0, len = data.length; index < len; index++) {
data[index] = data[index] * 2;
}
for (var index = 0, len = data.length; index < len; index += 1) {
data[index] = data[index] * 2;
}
Run Code Online (Sandbox Code Playgroud)
从几个基准测试中获得数据之后,我注意到Firefox平均每秒执行大约15次操作,而Chrome正在做大约300次操作.

我认为JaegerMonkey和v8在速度方面相当可比?我的基准测试是否存在缺陷,是Firefox在这里进行某种限制还是在Javascript解释器的性能之间存在差距?
更新:感谢jfriend00,我得出结论,性能上的差异并不完全是由于循环迭代,如此版本的测试用例所示.正如您所看到的,Firefox速度较慢,但没有我们在初始测试用例中看到的差距那么大.
那么为什么声明,
data[index] = data[index] * 2;
Run Code Online (Sandbox Code Playgroud)
在Firefox上这么慢?
数组在JavaScript中很棘手.您创建它们的方式,填充它们的方式(以及具有什么值)都会影响它们的性能.
引擎使用两种基本实现.最简单,最明显的一个是连续的内存块(就像一个C数组,有一些元数据,如长度).这是最快的方式,理想情况下,大多数情况下都是您想要的实现方式.
问题是,JavaScript中的数组只需分配给任意索引就会变得非常大,留下"漏洞".例如,如果您有一个小数组:
var array = [1,2,3];
Run Code Online (Sandbox Code Playgroud)
并为大索引分配值:
array[1000000] = 4;
Run Code Online (Sandbox Code Playgroud)
你会得到一个像这样的数组:
[1, 2, 3, undefined, undefined, undefined, ..., undefined, 4]
Run Code Online (Sandbox Code Playgroud)
为了节省内存,大多数运行时将转换array为"稀疏"数组.基本上,哈希表,就像常规JS对象一样.一旦发生这种情况,读取或写入索引就会从简单的指针算法变为更复杂的算法,可能还有动态内存分配.
当然,不同的运行时使用不同的启发式方法来决定何时从一种实现转换为另一种实现,因此在某些情况下,例如,针对Chrome进行优化会损害Firefox中的性能.
在你的情况下,我最好的猜测是向后填充数组导致Firefox使用稀疏数组,使其变慢.