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