Object.observe () JavaScript API 允许任何一段代码接收任何 JavaScript 对象的所有属性更改的更改通知。
这不会严重影响 JavaScript 引擎(即 V8)可以执行的代码生成和性能优化吗?如果必须生成更改通知,生成的本机代码现在似乎必须检查对对象的每一次写入。无法静态确定给定对象是否设置了通知。因此无法优化检查。
似乎任何符合标准的 JavaScript 引擎现在都因为这个 API 而陷入永久性和严重的性能损失。
Object.observe () JavaScript API 允许任何一段代码接收任何 JavaScript 对象的所有属性更改的更改通知。
这不会严重影响 JavaScript 引擎(即 V8)可以执行的代码生成和性能优化吗?如果必须生成更改通知,生成的本机代码现在似乎必须检查对对象的每一次写入。无法静态确定给定对象是否设置了通知。因此无法优化检查。
似乎任何符合标准的 JavaScript 引擎现在都因为这个 API 而陷入永久性和严重的性能损失。
现代 JavaScript 引擎利用内联缓存和自适应重新编译技术来最小化动态调度对生成代码的影响。
如果我们谈论 V8,那么是否观察到对象的事实编码在其隐藏类中。内联缓存存根和优化代码都已经根据某个预期值检查隐藏类以确定对象是否具有预期形状。同样的检查提供了关于是否观察到对象的信息。因此,与非观察对象一起工作的代码路径没有任何变化。开始观察对象的处理方式与更改其形状的方式相同:对象的隐藏类被切换到不同的类,并设置了观察位:您可以阅读Runtime_SetIsObserved
以查看此内容。
类似的推理适用于系统中在优化代码中省略守卫的部分,而是根据“形状”假设取消优化代码:一旦观察到对象,所有基于未观察到该对象的假设的优化代码都将被取消优化。因此,对于未观察到的物体,再一次没有任何代价。
也就是说,Object.observe
V8 中的当前实现使观察到的对象付出了高昂的代价,因为它将它们标准化(将它们转换为字典表示)并且需要通过运行时系统来回往返以进行观察记录。但是以后要显着降低这个成本并没有固有的技术困难。
这不会严重影响 JavaScript 引擎(即 V8)可以执行的代码生成和性能优化吗?
是的。就像 Proxies、Getters/Setters 甚至原型对象一样——它们在 JavaScript 中都是动态的。
然而,由于它们的异步性,新的(和更好的)优化是可能的;他们可以使其他效率更低的代码过时。引用和谐草案中的目标:
- 无需包装器或代理对象,提供内存效率和对象标识
- 在对象上添加/删除属性时更改通知
- 更改对象属性的属性描述符修改通知
- 对象手动指示访问器属性何时更改的能力
- 可在引擎中有效实施
- 对当前 ES 的简单、有针对性的扩展
- 异步通知更改,但允许同步获取更改等待交付