同步生成器的每个 `yield` 是否都不可避免地分配一个新的 `{value, done}` 对象?

问题描述

MDN 说:

yield 关键字导致调用生成器的 next() 方法返回一个具有两个属性的 IteratorResult 对象:value 和 done。 value属性是yield表达式求值的结果,done为false,表示生成函数还没有完全完成。

我在 Chrome 91.0.4472.77 中运行了一个测试,它似乎每次都是一个新对象。如果处理是细粒度的(大量迭代,每次计算量低),这似乎非常浪费。为了避免不可预测的吞吐量和 GC 卡顿,这是不可取的。

为了避免这种情况,我可以定义一个迭代器函数,在那里我可以控制(确保)每个 {value,done}next() 对象的重用,从而导致属性值就地修改,即。没有为新的 {value,done} 对象分配内存。

我是否遗漏了什么,或者生成器是否具有这种固有的产生垃圾的性质?如果我所做的只是 {value,done} 即,哪些浏览器足够聪明,不会分配新的 const {value,done} = generatorObject.next(); 对象。我不可能获得对象的句柄,即。引擎没有理由分配一个新对象?

解决方法

ECMAScript 规范要求生成器为每个 yield 分配一个新对象,因此所有兼容的 JS 引擎都必须这样做。

如果可以证明程序的可观察行为不会因为这种优化而改变,那么理论上 JS 引擎可以重用生成器的结果对象,例如当生成器的唯一用途是在 { {1}} 语句。但是,我不知道有任何引擎(至少在流行的 Web 浏览器中使用的引擎)会执行此操作。像这样的优化在 JavaScript 中是一个非常困难的问题,因为它是动态的。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...