【问题标题】:Do suspended generator functions have performance costs?暂停的生成器功能是否有性能成本?
【发布时间】:2017-10-31 02:58:52
【问题描述】:

永久挂起的函数生成器是否有性能成本?

例如,下面的代码将不断地yield 值,直到达到for 循环中d 的值。

出于问题的目的,我们有意阻止生成器达到done 的状态。这样做有资源成本吗?当然,理论上很容易向生成器表明我们实际上是done,但这有关系吗?为什么不让它永远挂起,直到它需要再次使用?

var fruits = ['apple', 'pear', 'strawberry']

function* fruitGenerator(items) {
  var numberOfItems = items.length
  var i = 0

  while (true) {
    yield items[i]
    i++
    if (i === numberOfItems) {
      i = 0
    }
  }
}

var multipleFruits = fruitGenerator(fruits)

for (var d = 0 ; d < 10; d++) {
  console.log(multipleFruits.next())
}

出于所有意图和目的,让我们假设对于这个示例,我不能使用常规的 for 循环。

【问题讨论】:

  • “出于所有意图和目的,让我们假设对于此示例” - 不是“对于 this 示例”与“ 所有意图和目的”?无论如何,如果调用次数不多,任何生成器函数可能永远不会完成,即使它没有被故意编码为无限循环 - 我不认为这是一个问题。
  • 我不确定您所说的“性能成本”是什么意思。内存大小,速度?与什么相比 - 结束并重新实例化生成器?
  • 性能成本是指内存大小和速度。它的生成器功能是否与标准 for 循环一样快?还是比forEach慢吗?暂停的生成器在等待重新调用时是否存储在内存中?如果需要,结束生成器并稍后重新实例化是否更节省内存?
  • @Modermo 当你周围有很多挂起的生成器对象时,它们确实会消耗额外的内存。但用完的发电机也是如此。没有区别。并且只要没有指向生成器的引用,它就会像任何其他对象一样被 GC,无论它是耗尽还是挂起。

标签: javascript function generator


【解决方案1】:

生成器函数有自己的执行上下文,每次生成器函数为resumed 时都必须恢复它。当一个生成器函数没有被执行时,它的执行上下文被存储在一个内部属性槽中,[[GeneratorContext]],geerator 对象。

从某种意义上说,使用生成器函数有任何开销,答案是肯定的,它们需要恢复已保存的执行。您是否能够使用分析工具检测它们,可能不是 - 所有 JavaScript 操作都有标准中定义的执行步骤,并且恢复和保存执行上下文不太可能比 JavaScript 操作中的其他步骤更重要。

从某种意义上说,生成器函数在不使用时是否会消耗执行时间,答案是否定的。 Generator objects 是在使用前驻留在内存中的对象。

【讨论】:

    猜你喜欢
    • 2018-12-19
    • 1970-01-01
    • 2021-09-05
    • 2015-04-23
    • 2017-05-09
    • 2020-03-01
    • 2017-06-26
    • 2015-03-04
    • 2012-08-21
    相关资源
    最近更新 更多