Javascript Object.observe()如何影响性能?

Javascript Object.observe()如何影响性能?,javascript,performance,javascript-engine,object.observe,Javascript,Performance,Javascript Engine,Object.observe,JavaScript API允许任何代码段接收任何JavaScript对象的所有属性更改的更改通知 这是否会严重影响JavaScript引擎(即V8)可以执行的代码生成和性能优化?如果必须生成更改通知,则生成的本机代码现在必须检查对对象的每次写入。无法静态确定给定对象是否设置了通知。因此,无法优化检查 似乎任何符合标准的JavaScript引擎现在都会因为这个API而永久性地严重损失性能 这不会严重影响JavaScript引擎(即V8)可以执行的代码生成和性能优化吗 对。与代理、getter/s

JavaScript API允许任何代码段接收任何JavaScript对象的所有属性更改的更改通知

这是否会严重影响JavaScript引擎(即V8)可以执行的代码生成和性能优化?如果必须生成更改通知,则生成的本机代码现在必须检查对对象的每次写入。无法静态确定给定对象是否设置了通知。因此,无法优化检查

似乎任何符合标准的JavaScript引擎现在都会因为这个API而永久性地严重损失性能

这不会严重影响JavaScript引擎(即V8)可以执行的代码生成和性能优化吗

对。与代理、getter/setter甚至原型对象一样,它们在JavaScript中都是动态的

然而,由于它们的异步性,新的(更好的)优化将成为可能;它们可能会使其他效率更低的代码过时。引用:

  • 无需包装器或代理对象,提供内存效率和对象标识
  • 添加/删除对象属性时的更改通知
  • 修改对象属性的属性描述符时的更改通知
  • 对象在访问器属性发生更改时手动指示的能力
  • 可在引擎中高效实施
  • 简单,有针对性,扩展到当前ES
  • 异步更改通知,但允许同步获取待交付的更改

现代JavaScript引擎利用内联缓存和自适应重新编译技术来最小化动态调度对生成代码的影响

如果我们谈论的是V8,那么不管对象是否被观察到,这个事实都被编码在它的隐藏类中。内联缓存存根和优化代码都已根据某个预期值检查隐藏类,以确定对象是否具有预期形状。同样的检查给出了关于是否观察到物体的信息。因此,处理未观察到的对象的代码路径不会发生任何更改。开始观察对象的方式与更改其形状的方式相同:对象的隐藏类将切换到另一个隐藏类,并设置观察位:您可以通过读取来查看此信息

类似的推理适用于在优化代码中省略防护装置的系统部分,而是根据“形状”假设对代码进行去优化:一旦观察到一个对象,所有基于未观察到该对象的假设的优化代码都将被去优化。因此,对于未被观测到的物体,同样没有付出任何代价


这就是说,V8中
Object.observe
的当前实现使得被观察对象付出了高昂的代价,因为它将它们规范化(将它们转换为字典表示),并且需要通过运行时系统进行往返以进行观察记录。但是,在以后大幅降低这一成本方面没有固有的技术困难。

“不可能静态确定给定对象是否设置了通知”-为什么?@Bergi您会怎么做?静态意味着不运行代码或检查对象。不过,这要求引擎永远采用动态“隐藏类”方法。现在,可以使用静态分析或类型注释(在未来的JavaScript版本中)解决更多这些专门化优化。这将永远是不可能的。现在,JS的速度永远也比不上Java或.NET,即使有完美的类型信息;类型注释是未来的一种假设,即使引入的引擎必须保持隐藏类以快速运行“老派”未注释代码以实现向后兼容性。第二,比较语言X和语言Y的速度的一些抽象概念不是建设性的,您应该指定基准,我们正在讨论的语言模式等。最后我特别概述了执行代码时不包含任何检查的方法。最后一种方法依赖于Object.observe对可能写入观察对象的代码进行去优化。这非常类似于在附加调试器时对代码进行去优化。根据实现方式的不同,它可以对所有对象或只对受影响的函数进行去优化。没有办法只对受影响的函数进行去优化,因为任何对象(除非通过转义分析证明永远不会转义到观察代码中,甚至在eval的帮助下也不会)都可以被观察到(并且在任何事件循环迭代中都会发生变化).; 别误会我的意思,你的回答很有用,过几天就会被接受。我只是觉得这个特殊的功能提供了一种我们以前从未有过的、不可逆转的性能锁定。我在这里试图说明的是,如果你不使用
对象。观察
你绝对不需要支付任何费用。当您使用它时,特定的成本将取决于实现和应用程序本身。