为什么在这个例子中使用生成器函数比填充和迭代数组要慢?
为什么在这个例子中使用生成器函数比填充和迭代数组要慢?
两个函数的故事
我有一个函数,它会将一个数组填充到指定的值:
function getNumberArray(maxValue) { const a = []; for (let i = 0; i < maxValue; i++) { a.push(i); } return a; }
还有一个类似的生成器函数,它会逐个生成每个值:
function* getNumberGenerator(maxValue) { for (let i = 0; i < maxValue; i++) { yield i; } }
测试运行器
我为这两种情况编写了以下测试:
function runTest(testName, numIterations, funcToTest) { console.log(`Running ${testName}...`); let dummyCalculation; const startTime = Date.now(); const initialMemory = process.memoryUsage(); const iterator = funcToTest(numIterations); for (let val of iterator) { dummyCalculation = numIterations - val; } const finalMemory = process.memoryUsage(); // 注意:formatNumbers 可在此处找到:https://jsfiddle.net/onz1ozjq/ console.log(formatNumbers `Total time: ${Date.now() - startTime}ms`); console.log(formatNumbers `Rss: ${finalMemory.rss - initialMemory.rss}`); console.log(formatNumbers `Heap Total: ${finalMemory.heapTotal - initialMemory.heapTotal}`); console.log(formatNumbers `Heap Used: ${finalMemory.heapUsed - initialMemory.heapUsed}`); }
运行测试
然后像这样运行这两个函数:
const numIterations = 999999; // 999,999 console.log(formatNumbers `Running tests with ${numIterations} iterations...\n`); runTest("Array test", numIterations, getNumberArray); console.log(""); runTest("Generator test", numIterations, getNumberGenerator);
我得到类似于以下结果:
Running tests with 999,999 iterations... Running Array test... Total time: 105ms Rss: 31,645,696 Heap Total: 31,386,624 Heap Used: 27,774,632 Running Function generator test... Total time: 160ms Rss: 2,818,048 Heap Total: 0 Heap Used: 1,836,616
注意:我在Windows 8.1上的Node v4.1.1上运行这些测试。我没有使用转译器,通过node --harmony generator-test.js
来运行它。
问题
数组的内存使用增加是显而易见的... 但为什么数组总是能得到更快的结果?是什么导致了这种减速?yield操作是否很耗时?或者我检查的方法有问题吗?