为什么在这个例子中使用生成器函数比填充和迭代数组要慢?

10 浏览
0 Comments

为什么在这个例子中使用生成器函数比填充和迭代数组要慢?

两个函数的故事

我有一个函数,它会将一个数组填充到指定的值:

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操作是否很耗时?或者我检查的方法有问题吗?

0