同步发电机的每个 `yield` 都不可避免地分配一个新的 `{value, done}` 对象吗?
Does each `yield` of a synchronous generator unavoidably allocate a fresh `{value, done}` object?
MDN 说:
The yield keyword causes the call to the generator's next() method to return an IteratorResult object with two properties: value and done. The value property is the result of evaluating the yield expression, and done is false, indicating that the generator function has not fully completed.
我 运行 在 Chrome 91.0.4472.77 中进行了测试,它似乎每次都是一个新对象。如果处理是细粒度的(大量迭代,每次迭代都具有低计算量),这似乎非常浪费。为了避免不可预测的吞吐量和 GC 卡顿,这是不可取的。
为了避免这种情况,我可以定义一个迭代器函数,我可以在其中控制(确保)每个 next()
对 {value, done}
对象的重用,从而导致 属性 值成为就地修改,即。没有为新的 {value, done}
对象分配内存。
我是不是遗漏了什么,或者生成器是否具有这种固有的产生垃圾的特性?如果我所做的只是 const {value, done} = generatorObject.next();
,哪些浏览器足够聪明,不会分配新的 {value, done}
对象。我不可能获得对象的句柄,即。引擎没有理由分配新对象?
ECMAScript 规范要求生成器为每个 yield 分配一个新对象,因此所有兼容的 JS 引擎都必须这样做。
理论上,如果 JS 引擎可以证明程序的可观察行为不会因这种优化而改变,例如当生成器的唯一用途是在const {value, done} = generatorObject.next()
语句。但是,我不知道有任何引擎(至少是流行的网络浏览器中使用的引擎)执行此操作。像这样的优化在 JavaScript 中是一个非常困难的问题,因为它具有动态特性。
MDN 说:
The yield keyword causes the call to the generator's next() method to return an IteratorResult object with two properties: value and done. The value property is the result of evaluating the yield expression, and done is false, indicating that the generator function has not fully completed.
我 运行 在 Chrome 91.0.4472.77 中进行了测试,它似乎每次都是一个新对象。如果处理是细粒度的(大量迭代,每次迭代都具有低计算量),这似乎非常浪费。为了避免不可预测的吞吐量和 GC 卡顿,这是不可取的。
为了避免这种情况,我可以定义一个迭代器函数,我可以在其中控制(确保)每个 next()
对 {value, done}
对象的重用,从而导致 属性 值成为就地修改,即。没有为新的 {value, done}
对象分配内存。
我是不是遗漏了什么,或者生成器是否具有这种固有的产生垃圾的特性?如果我所做的只是 const {value, done} = generatorObject.next();
,哪些浏览器足够聪明,不会分配新的 {value, done}
对象。我不可能获得对象的句柄,即。引擎没有理由分配新对象?
ECMAScript 规范要求生成器为每个 yield 分配一个新对象,因此所有兼容的 JS 引擎都必须这样做。
理论上,如果 JS 引擎可以证明程序的可观察行为不会因这种优化而改变,例如当生成器的唯一用途是在const {value, done} = generatorObject.next()
语句。但是,我不知道有任何引擎(至少是流行的网络浏览器中使用的引擎)执行此操作。像这样的优化在 JavaScript 中是一个非常困难的问题,因为它具有动态特性。