Object.observe()如何影响性能

How does Object.observe() affect performance?

本文关键字:影响 性能 observe Object 何影响      更新时间:2023-09-26

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

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

由于这个API,似乎任何符合标准的JavaScript引擎现在都被锁定在永久性和严重的性能损失中。

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

如果我们说的是V8,那么对象是否被观察的事实是在它的隐藏类中编码的。内联缓存存根和优化代码都已经根据一些预期值检查隐藏类,以确定对象是否具有预期的形状。同样的检查给出了对象是否被观察到的信息。因此,与未观察到的对象一起工作的代码路径没有任何变化。开始观察对象的方式与改变它的形状相同:对象的隐藏类被切换到另一个,并设置了观察位:您可以读取Runtime_SetIsObserved以查看此操作。

类似的推理也适用于在优化代码中省略保护,而是根据"形状"假设对代码进行反优化的部分:一旦对象被观察到,所有依赖于该对象未被观察到的假设的优化代码将被反优化。因此,对于未观察到的物体,又没有付出任何代价。

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

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

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

然而,由于它们的异步性,新的(更好的)优化将是可能的;它们可以使其他更低效的代码过时。引用和谐草案目标:

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