Javascript ES6 产量与 Python 中的产量

Pra*_*een 5 javascript python ecmascript-6

我已经研究 Python 和 JS 有一段时间了,想了解 Python 和 ES6 中生成器的产量之间的行为差​​异

在 python 中使用 yield 可以节省内存,因为它一次生成 1 个项目。这与 ES6 中的产量相同吗?

Sha*_*ger 4

简短的回答是“是”。

简化的长答案是“是的,尽管生成器有一些开销(固定的意思是它不会随着要生成的项目数量而改变),当要生成的项目数量很小时,这会使节省消失。” (但当然,在这种情况下,总成本足够小,无论如何都不重要)

对长答案的过于复杂的警告:

CPython(参考Python解释器)对代码的优化很少;它可以在非常有限的情况下进行小的窥视孔优化(例如,它可以转换1 + 2 + x3 + x字节码,但由于运算符重载和操作顺序,它无法转换x + 1 + 2x + 3,因为它不能假设x + 1将返回 an int,并且它无法知道加法对于任何类型都是关联x的)。因此,当您在 CPython 中使用生成器时,它将始终在运行时作为生成器执行。

相比之下,在大多数现代浏览器上,JavaScript 引擎使用JIT-ing将 JavaScript 代码编译为本机代码;它可以进行推测/自适应优化,编译为假设特定类型和值的代码,并且仅在假设失败时才解释原始 JS。这意味着您实际上无法确定在生成器代码在热循环中执行的情况下会做什么(从长远来看,昂贵的分析和优化被认为是值得的)。

如果 JS 引擎确定生成器通常产生少量可以提前计算的输出,这些输出通常会被完全消耗,那么生成过程没有明显的副作用,并且它会更高效而不是内存过于密集,它完全有权利生成本机代码,该代码实际上并不创建或运行生成器,而是生成一个Array输出(或者对于数字之类的东西,可能是一个 ES6类型数组以减少内存使用)。我不知道哪些 JS 引擎(如果有的话)可能会尝试执行这样的优化,但考虑到过去七年左右 JS 引擎的技术水平变化得有多快(最慢的常用现代 JS 引擎是可能比 2008 年 9 月 1 日V8发布之前最快的引擎至少快 10 倍),今天发生的优化明天可能很容易改变。