【问题标题】:How does Object.observe() affect performance?Object.observe() 如何影响性能?
【发布时间】:2013-02-27 14:23:56
【问题描述】:

Object.observe() JavaScript API 允许任何代码段接收任何 JavaScript 对象的所有属性更改的更改通知。

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

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

【问题讨论】:

  • "无法静态确定给定对象是否设置了通知" - 为什么?
  • @Bergi 你会怎么做?静态意味着不运行代码或检查对象。

标签: javascript performance javascript-engine object.observe


【解决方案1】:

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

如果我们谈论的是 V8,那么是否观察到对象的事实被编码在它的隐藏类中。内联缓存存根和优化代码都已经根据某个预期值检查隐藏类以确定对象是否具有预期形状。同样的检查提供了关于是否观察到对象的信息。因此,与非观察对象一起工作的代码路径没有任何变化。开始观察对象的处理方式与更改其形状相同:对象的隐藏类被切换到不同的隐藏类,并设置了观察位:您可以阅读Runtime_SetIsObserved 看到这一点。

类似的推理适用于系统中省略优化代码中的守卫,而是根据“形状”假设取消优化代码的部分:一旦观察到对象,所有基于该对象未被观察到的假设的优化代码都将被去优化。因此,对于未观察到的物体,再次没有任何代价。

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

【讨论】:

  • 不过,这要求引擎永远采用动态的“隐藏类”方法。现在,可以使用静态分析或类型注释(在未来的 JavaScript 版本中)解决更多这些专业化优化。现在这将永远不可能。即使有完美的类型信息,JS 现在也永远不会像 Java 或 .NET 这样快。
  • 首先让我注意到,对当前形式的完整 JavaScript 进行静态类型分析过于昂贵且不切实际;和类型注释是明天的假设,即使引入引擎也必须保留隐藏类以快速运行“老派”未注释代码以实现向后兼容性。其次比较语言 X 与语言 Y 的速度的一些抽象概念是没有建设性的,你应该指定基准,我们正在讨论的语言模式等。最后我特别概述了执行代码包含 no 检查的方法.
  • 最后一种方法依赖于 Object.observe 对可能写入观察对象的代码进行反优化。例如,当附加了调试器时,它与反优化代码非常相似。根据事物的实现方式,它可以取消优化所有内容或仅取消受影响的功能。
  • 没有办法只对受影响的函数进行反优化,因为可以观察到任何对象(除非通过转义分析证明永远不会转入观察代码,即使在 eval 的帮助下也不会)(并且可以在任何事件循环迭代中更改)。;不要误会我的意思,你的回答很有用,过几天就会被接受。我只是觉得这个特殊功能提供了一种我们以前从未有过的性能锁定,这是不可逆转的。
  • 我想在这里说明的是,如果您不使用Object.observe,您绝对无需支付任何费用。当您使用它时,具体成本将取决于实现和应用程序本身。
【解决方案2】:

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

是的。就像 Proxies、Getters/Setters 甚至原型对象一样——它们在 JavaScript 中都是动态的。

但是,由于它们的异步性,新的(和更好的)优化是可能的;他们可以使其他效率更低的代码过时。引用Goals from the harmony draft

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

【讨论】:

    猜你喜欢
    • 2013-04-12
    • 1970-01-01
    • 1970-01-01
    • 2018-11-16
    • 2012-01-11
    • 2011-01-08
    • 2015-05-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多