【问题标题】:How does extending the prototype chain increase performance in this case?在这种情况下,扩展原型链如何提高性能?
【发布时间】:2018-02-20 20:05:02
【问题描述】:

我有一个长期的假设,即深度 prototype chains 会导致属性访问器的性能下降。我试图在 hide the getter or add in the proto Object 上解释这一点,但快速的 benchmark I threw together 导致的结果与我的预期完全相反。

这里发生了什么?我是否遗漏了一些明显的东西,或者这是否完全表明我(和其他人)对prototype 链上属性访问器性能的假设是错误的?

设置

const object1 = {
  foo: 'Hello, World!',
  get bar () { return this.foo }
};

const object2 = Object.assign(Object.create({
  get bar () { return this.foo }
}), {
  foo: 'Hello, World!'
});

let result;

测试 1

(控制,没有prototype

result = object1.bar;

测试 2

(实验,prototype

result = object2.bar;

结果

测试 1 的运行速度比测试 2 慢 92.85%,这意味着将 get bar () {} 放在 prototype 链中而不是放在对象自身的属性中会导致属性访问器的速度提高 14 倍。请参阅Object.create() 了解对象的布局有何不同。

测试 1

79,323,722 次操作/秒 ±0.34%

测试 2

1,108,762,737 次操作/秒 ±0.15%

使用 Google Chrome 63.0.3239.132(官方版本)(64 位)在 Windows 10 Intel i7-7700K CPU @ 4.20GHz 上测试

【问题讨论】:

  • (FWIW,基准测试在 Firefox 60 中两者之间没有区别。18 亿次操作/秒与 Chrome 64 的 60 和 8.9 亿次操作/秒)
  • 运行时可以随意折叠链。
  • @Pointy 当然,但这并不能解释为什么它更快而不是可比
  • @Akxe:该链接指向导致性能变化的补丁,而不是有关命中的错误报告。

标签: javascript performance optimization prototype getter


【解决方案1】:

据我所知,这些细节仅适用于 V8 引擎,我不确定这如何直接映射到 Firefox 的实现。

没有原型,V8 正在创建隐藏类来支持对象的属性。对于每个新属性,都会创建一个新的隐藏类,然后创建从前一个隐藏类到新隐藏类的转换。

但是,原型不会发生这种情况,并且在我就该主题进行的对话中这是一个鲜为人知的事实。换句话说,是的,原型更快。

为了优化原型,V8 以不同于常规过渡对象的方式跟踪它们的形状。我们没有跟踪转换树,而是为原型对象定制隐藏类,并始终保持快速 -Toon Verwaest (V8 dev)

此设置均发生在Dynamic Machine Code Generation 期间。您看到的两种设置之间的区别在于更复杂的隐藏类路径与更自定义的路径之间的区别。或者,顾名思义,fastPropertiesWithPrototype 对象和 slowProperties 对象的区别,后者使用字典模式。

【讨论】:

  • 我认为字典模式和隐藏类转换表是两个独立的机制。您是说{ foo: 'Hello, World!', get bar () { return this.foo } } 的实例化将对象配置为字典模式并且还 创建了从{ foo: 'Hello, World!' } 转换的第二个隐藏类?我认为隐藏类用于避免切换到字典模式。
  • 字典中的条目应该是通过隐藏类的路径。
  • 啊,我完全误解了这一点。谢谢你解释这个重要的细节。还有一个问题。此实现仅适用于 V8?或者 SpiderMonkey 是否也使用字典模式和隐藏类转换来实现慢速对象?
  • @PatrickRoberts - 复杂的路径可能正在使用 fastProperties(与 slowProperties 相对),它们只是稍微快一点。它们仍然比 fastPropertiesWithPrototype 对象慢。我不确定属性存储何时成为查找而不是在创建期间线性访问的确切触发器,但从我读到的内容看来,创建匿名对象确实会创建一个带有查找的属性存储。
  • @PatrickRoberts - 我会在我的回答中就实现做一个说明,因为我相信这只是 V8 相关的。抱歉,从我认为相关的基准来看,当我使用性能示例时,它在 chrome 中显示出非常相似的结果。
猜你喜欢
  • 2017-04-20
  • 2021-10-28
  • 1970-01-01
  • 1970-01-01
  • 2020-12-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多