JavaScriptにおけるメモリ消費の最適化

作成されたすべての変数は、 コンピュータのRAM(メモリ)に保存されます。 時には、考えなしにコードを書くことで、 消費メモリが急激に増加することがあります。

具体例を見てみましょう。 ここに、 1 から 100000000 までの 整数の合計を見つけるという課題があるとします。 与えられた範囲の整数で配列を埋める 関数があるとしましょう:

javascriptfunction fillArr(a, b) {
  let res = [];
  
  for (let i = a; i <= b; i++) {
    res.push(i);
  }
  
  return res;
}

また、配列の要素の合計を求める 関数もあるとします:

javascriptfunction getSum(arr) {
  let sum = 0;
  
  for (let elem of arr) {
    sum += elem
  }
  
  return sum;
}

これらの関数を組み合わせることで、 与えられた課題を簡単に解決できます:

javascriptlet sum = getSum(fillArr(1, 100000000));

エレガントな解決策が得られました。しかし、 これには問題があります:膨大な量のRAMを 消費することです。

計算してみましょう。関数 fillArr は 100000000 個の数値を持つ配列を作成します。 JavaScriptが1つの数値に 2 バイトを割り当てると仮定すると、 この配列を保存するには 200000000 バイト、つまり約 200 メガバイトのRAMが必要になります。

しかし実際には、JavaScriptでは配列を保存する際の オーバーヘッドが非常に大きいため、 はるかに多くのRAMが必要になります。

この問題を理解すれば、この課題を解決し、 ほとんどRAMを消費しない関数を 簡単に作ることができます:

javascriptfunction getNumsSum(max) {
  let sum = 0;
  
  for (let i = 1; i <= max; i++) {
    sum += i;
  }
  
  return sum;
}

私たちの関数を使って課題を解決します:

javascriptlet sum = getNumsSum(100000000);
Задание 1

とあるプログラマーに、与えられた範囲内で 7 で割り切れる数の個数を 見つける課題がありました。 彼は次のように解決しました:

javascriptlet arr = [];

for (let i = 0; i <= 1000; i++) {
  if (i % 7 == 0) {
    arr.push(i);
  }
}

console.log(arr.length);

このコードの何が問題かを説明してください。 より最適なコードに書き直してください。

Задание 2

とあるプログラマーに、ある数の約数の和を 求める課題がありました。 彼は次のように解決しました:

javascriptfunction 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);

このコードの何が問題かを説明してください。 より最適なコードに書き直してください。