【问题标题】:Large performance variance with Javascript object instantiation size & methodsJavascript 对象实例化大小和方法的性能差异很大
【发布时间】:2015-12-11 20:10:54
【问题描述】:

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

任何人都可以阐明以下 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}”如此优越?

【问题讨论】:

  • fyi,在 Chrome 中,差异更加夸张。
  • 在 Firefox 42 上差异很小
  • 可能和JIT进来的时候有关
  • 我认为这与缓存有关。

标签: javascript performance object instantiation microbenchmark


【解决方案1】:

这样的性能差异通常不是由于语言 javascript,而是由于该语言的实现

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

由于那里有多种实现方式 - 它们在不断发展 - 并且浏览器没有吐出生成的程序集的习惯,因此没有一般的答案。

例如,在 FF 45 上,我在所有四种情况下都获得了几乎相同的性能:

大概 JIT 编译器足够聪明,可以在这里执行死代码消除,因此我们本质上是在对空循环进行基准测试。换句话说,这个结果显示了编译器的优化程度,而不是对象分配的成本。

Making the objects escape 进入全局范围会产生以下结果,这与预期的结果差不多:

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

所以未来的浏览器版本可能会再次“打破”这个基准。

微基准测试是一项棘手的工作。

【讨论】:

  • 对,第一个 FF 结果肯定是由于某些“高级”浏览器工作有效地忽略了大部分实例化。
【解决方案2】:

我的猜测是基于 hashmap 的表单是本地执行的,而基于构造函数的表单执行一个需要解释的函数。我想这种解释工作会导致性能差异。

那么 8 属性阈值呢? HashMap 需要预先设置大小超过它应该包含的最大值数(如果没有,访问时间会增加)。如果某些浏览器供应商选择了较低的值(例如 8-10),则每次尝试存储超过 8 个项目都会降低性能。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-10-01
    • 2019-09-25
    • 2020-12-16
    • 2021-10-11
    • 1970-01-01
    • 2012-09-03
    • 1970-01-01
    • 2012-03-29
    相关资源
    最近更新 更多