具有Javascript对象实例化大小和方法的大型性能差异

问题描述 投票:4回答:2

我已经注意到各种对象实例化方法之间的显着性能差异。此外,似乎对象的大小(即,属性数)有时有时非常重要。

有人可以阐明以下jsperf的结果吗?http://jsperf.com/objects-w-more-less-8-properties/5

var thisobj = {a:1,b:2,c:3,d:4,e:5,f:6,g:7,h:8} 

这似乎是创建新对象的快速方法

var thisobj = {a:1,b:2,c:3,d:4,e:5,f:6,g:7,h:8,i:9}

这要慢得多...唯一的区别是第9个值

var thisobj = new objsm(1,2,3,4,5,6,7,8); 

var thisobj = new objlg(1,2,3,4,5,6,7,8,9);

彼此之间相差不大(大约与您期望的相差不大),但是它们与上面的“动态”定义的对象仍然相差很大。它们的对象在这里定义:

    var objsm = function (a,b,c,d,e,f,g,h) {
    this.a = a; this.b = b; this.c = c; this.d = d; this.e = e; this.f = f; this.g = g; this.h = h;}

var objlg = function (a,b,c,d,e,f,g,h,i) {
this.a = a; this.b = b; this.c = c; this.d = d; this.e = e; this.f = f; this.g = g; this.h = h; this.i = i; }

为什么“ var thisobj = {a:1,b:2,c:3,d:4,e:5,f:6,g:7,h:8}”如此优越?

javascript performance object instantiation microbenchmark
2个回答
1
投票

这样的性能差异通常不是由于language javascript而引起的,而是由于该语言的implementation

[其他因素,例如堆占用率(以及由此产生的GC成本)也会影响性能。

由于存在多种实现-不断发展-并且浏览器没有吐出生成的程序集的习惯,所以没有通用的答案。

例如,在FF 45上,我在所有四种情况下的性能都差不多:

FF45 benchmark run

假定JIT编译器足够聪明,可以在此处执行消除死代码的功能,因此我们实质上是对空循环进行基准测试。换句话说,此结果显示了编译器的优化水平,而不是对象分配的成本。

Making the objects escape进入全局范围会产生以下结果,与预期结果有关:

enter image description here

请注意,足够先进的编译器™可以通过观察它们都写入同一变量而无需在两次迭代之间进行读取,从而可以消除循环中除最后一次分配以外的所有分配。

因此将来的浏览器版本可能会再次“破坏”该基准。

微基准测试是棘手的事情。


0
投票

我的猜测是,基于哈希图的表单是natively执行的,而基于构造函数的表单会执行需要解释的函数。我想这种解释的努力会导致表演的差异。

以及8属性阈值如何? HashMap需要预先设置大小,大小为超过其应包含的最大数量(否则,访问时间将增加)。如果某些浏览器供应商选择了一个较低的值(例如8-10),则每次尝试存储8个以上的项目都会降低性能。

但是,您提到的jsperf中的main关联不是通过测试,而是通过浏览器:每个浏览器在所有测试中显示的结果都非常相似,这很合理。

© www.soinside.com 2019 - 2024. All rights reserved.