Optymalizacja zużycia pamięci w JavaScript
Wszystkie utworzone zmienne są przechowywane w pamięci operacyjnej komputera. Czasami bezmyślne pisanie kodu może gwałtownie zwiększyć zużywaną pamięć.
Spójrzmy na przykład.
Załóżmy, że mamy zadanie znaleźć
sumę liczb całkowitych od 1
do 100000000.
Załóżmy, że mamy funkcję,
która wypełnia tablicę
liczbami całkowitymi z zadanego
zakresu:
function fillArr(a, b) {
let res = [];
for (let i = a; i <= b; i++) {
res.push(i);
}
return res;
}
Załóżmy, że mamy również funkcję, która znajduje sumę elementów tablicy:
function getSum(arr) {
let sum = 0;
for (let elem of arr) {
sum += elem
}
return sum;
}
Za pomocą kombinacji tych funkcji można łatwo rozwiązać postawione zadanie:
let sum = getSum(fillArr(1, 100000000));
Otrzymaliśmy eleganckie rozwiązanie. Jest w nim jednak problem: zużywa ogromną ilość pamięci operacyjnej.
Policzmy. Funkcja fillArr
tworzy tablicę z 100000000 liczbami.
Załóżmy, że JavaScript przeznacza na liczbę 2 bajtów
- wtedy do przechowania naszej tablicy będzie potrzebne
200000000 bajtów, czyli około
200 megabajtów pamięci operacyjnej.
Ale w rzeczywistości potrzeba będzie znacznie więcej pamięci operacyjnej z powodu bardzo dużych narzutów w JavaScript przy przechowywaniu tablicy.
Rozumiejąc problem, łatwo jest stworzyć funkcję, która rozwiązuje zadanie i praktycznie nie zużywa pamięci operacyjnej:
function getNumsSum(max) {
let sum = 0;
for (let i = 1; i <= max; i++) {
sum += i;
}
return sum;
}
Rozwiążmy zadanie za pomocą naszej funkcji:
let sum = getNumsSum(100000000);
Przed pewnym programistą stało zadanie znaleźć
liczbę liczb podzielnych bez reszty przez
7, znajdujących się w zadanym
przedziale. Rozwiązał je w następujący sposób:
let arr = [];
for (let i = 0; i <= 1000; i++) {
if (i % 7 == 0) {
arr.push(i);
}
}
console.log(arr.length);
Wyjaśnij, co jest nie tak z tym kodem. Przerób kod na bardziej optymalny.
Przed pewnym programistą stało zadanie znaleźć sumę dzielników liczby. Rozwiązał je w następujący sposób:
function getDivisors(num) {
let res = [];
for (let i = 1; i <= num; i++) {
if (num % i === 0) {
res.push(i);
}
}
return res;
}
function getSum(arr) {
let sum = 0;
for (let elem of arr) {
sum += elem
}
return sum;
}
let sum = getSum(getDivisors(320));
console.log(sum);
Wyjaśnij, co jest nie tak z tym kodem. Przerób kod na bardziej optymalny.