在这种情况下,扩展原型链如何提高性能? [英] How does extending the prototype chain increase performance in this case?

查看:97
本文介绍了在这种情况下,扩展原型链如何提高性能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个长期的假设,即深度 prototype 导致财产访问者的性能下降。我试图通过隐藏getter或添加来解释在proto对象中,当快速基准测试我在一起时导致了相反的结果我期待的是什么。

I've had a long-standing assumption that deep prototype chains resulted in performance deterioration for property accessors. I was trying to explain that on hide the getter or add in the proto Object when a quick benchmark I threw together resulted in quite the opposite outcome from what I was expecting.

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

What is going on here? Am I missing something obvious, or does this outright demonstrate that my (and others') assumption about the performance of property accessors on the prototype chain was wrong?

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



(控制,没有原型

Test 1

(control, without prototype)

result = object1.bar;



测试2



(实验,原型

Test 2

(experiment, with prototype)

result = object2.bar;



结果



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

Outcome

Test 1 ran 92.85% slower than Test 2, which means that placing get bar () {} in the prototype chain rather than in the object's own properties results in a 14x speed increase for the property accessor. See Object.create() to understand how the layout of the object is different.

79,323,722 ops / s±0.34%

79,323,722 ops/s ±0.34%

1,108,762,737 ops / s± 0.15%

1,108,762,737 ops/s ±0.15%

使用谷歌浏览器63.0.3239.132(官方版本)(64位)测试Windows 10英特尔i7-7700K CPU @ 4.20GHz

Tested on Windows 10 Intel i7-7700K CPU @ 4.20GHz using Google Chrome 63.0.3239.132 (Official Build) (64-bit)

推荐答案

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

To my knowledge, these details only apply to the V8 engine, I am not sure how directly this maps to the Firefox's implementation.

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

Without the prototype, V8 is creating hidden classes to support the properties of your object. For each new property, a new hidden class is created, and then a transition from the previous hidden class to the new one is created.

但是,这不会发生在原型,从我对这个主题的谈话中得到一些鲜为人知的事实。换句话说,是的,原型 更快。

However, this does not happen with prototypes, and is kind of a little known fact from the conversations I have had with regards to the topic. In other words, yes, prototypes are faster.


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

此设置全部发生在动态机器代码生成。您看到的两个设置之间的区别在于更复杂的隐藏类路径与更多自定义路径之间的差异。或者,按名称,fastPropertiesWithPrototype对象和slowProperties对象之间的差异,后者使用字典模式。

This setup all happens during Dynamic Machine Code Generation. The difference between the two setups that you are seeing is the difference between the more complex hidden class path versus the more custom path. Or, by name, the difference between the fastPropertiesWithPrototype object and the slowProperties object, the latter of which uses dictionary mode.

这篇关于在这种情况下,扩展原型链如何提高性能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆