Opowieść dwóch funkcjiDlaczego używa się funkcji generatora wolniejszej niż wypełnianie i iterowanie tablicy w tym przykładzie?
mam jedną funkcję, która wypełnia tablicę do określonej wartości:
function getNumberArray(maxValue) {
const a = [];
for (let i = 0; i < maxValue; i++) {
a.push(i);
}
return a;
}
i podobną funkcję generatora, że zamiast Plony każdą z wartości:
function* getNumberGenerator(maxValue) {
for (let i = 0; i < maxValue; i++) {
yield i;
}
}
Test Runner
pisałem ten test dla obu tych scenariuszy:
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();
// note: formatNumbers can be found here: 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}`);
}
uruchomione testy
Następnie po uruchomieniu tych dwóch tak:
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);
uzyskać wyniki podobne do tego:
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
Uwaga: używam tych e testy na węźle v4.1.1 w Windows 8.1. Nie używam transpilera i uruchamiam go wykonując node --harmony generator-test.js
.
Pytanie
Zwiększone zużycie pamięci jest oczywiście z oczekiwanym tablicy ... ale dlaczego ja konsekwentnie coraz szybszych wyników na tablicy? Co powoduje spowolnienie tutaj? Czy wydajność jest tylko kosztowną operacją? A może jest coś z metodą, którą robię, aby to sprawdzić?
Przepraszamy za głupie pytanie ... jaki to jest język? 'function *' nie wygląda jak składnia kodu JavaScript I, ani nie jest słowem kluczowym 'const'. –
@ sg.cc przepraszam, wiem, że może być mylące. To ES6 javascript-nie ES5. Możesz przeczytać o 'funkcji *' i innych funkcjach używanych tutaj [MDN] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*). –
W jakim środowisku korzystasz z tego kodu? Czy wspiera generatory natywnie, czy używasz transpilatora takiego jak Babel do generowania kodu ES5? –