首页 > 解决方案 > 仅存在 ES6 setter/getter 就会导致不相关函数 (V8) 的性能下降

问题描述

1)制作一个对象并给它一个简单的方法,例如,

let R = {
  f: (x) => Math.sqrt(x)
}

2) 对其性能进行基准测试,例如,调用 f(x) 几百万次 3) 现在添加一个 getter,例如,

let R = {
  f: (x) => Math.sqrt(x),
  get h() {return 0}
}

4) 再次对 f(x) 进行基准测试。chrome/node(V8 引擎)的性能显着下降。

对这种怪异有什么解释吗?

这是一个代码笔片段:https ://codepen.io/iiroullin/pen/XWbwoVQ

解决方法:

似乎以旧 (ES5) 方式定义 getter/setter 并不会破坏 V8 优化。因此,虽然他们正在消除 ES6 中的所有问题,但可以使用以下方法代替 (3):

Object.defineProperty(R, 'h', {get: () => 0})

等等所有的getter/setter。

另一个修复:

使用类,请看下面的答案

标签: javascriptnode.jsgoogle-chromev8

解决方案


我为此提交了一个错误:crbug.com/v8/10429

你能描述一下这是在什么情况下(除了微基准)出现的,特别是与在类上定义 getter 相比吗?以下似乎很快:

class C {
  f(x) { return Math.sqrt(x); }
  get h() { return 0; }
}
let R = new C();

for (...) {
  R.f(...);
}

我想使用类来定义非平凡的对象目前被认为是“最佳实践”;如果在某些情况下类不符合要求,那么最好知道这样引擎可以针对此类模式进行优化。


旁注@JaredSmith:术语“deopt”专门指当稍后在编译时做出的假设不成立时必须丢弃优化代码的情况。这不是这里发生的事情。


推荐阅读