「再帰」と「ループ」は同じ処理を実現できることが多いですが、性能面では違いがあります。初心者向けに整理してみます。
性能比較のポイント
1. 関数呼び出しのコスト
- 再帰
- 関数を呼ぶたびに「呼び出しスタック」に情報を積む(引数や戻り先など)。
- 呼び出しが深いとメモリを多く消費し、処理速度も遅くなる。
- ループ
- 1つの関数の中で変数を更新しながら繰り返すだけ。
- 関数呼び出しのオーバーヘッドがないので軽い。
2. メモリ使用量
- 再帰
- 呼び出しのたびにスタックフレームが積み重なる。
- 深さが大きいと「スタックオーバーフロー」になる危険がある。
- ループ
- 変数を1つ更新するだけなのでメモリ効率が良い。
3. 可読性
- 再帰
- ネスト構造や木構造の探索ではコードが短く直感的。
- ただし「深さが浅い単純な処理」では逆に読みにくい。
- ループ
- 回数が決まっている処理や単純な集計に向いている。
実際の例:配列の合計
ループ版(高速・省メモリ)
function sumLoop(arr) {
let sum = 0;
for (let i = 0; i < arr.length; i++) {
sum += arr[i];
}
return sum;
}
JavaScript再帰版(分かりやすいが遅い)
function sumRec(arr, i = 0) {
if (i === arr.length) return 0;
return arr[i] + sumRec(arr, i + 1);
}
JavaScript👉 性能面ではループが有利。
ただし、ネストした配列や木構造を処理する場合は再帰の方が圧倒的にシンプル。
✅ まとめ
| 観点 | ループ | 再帰 |
|---|---|---|
| 実行速度 | 速い | 遅い(関数呼び出しのオーバーヘッドあり) |
| メモリ効率 | 良い | 悪い(スタックを消費) |
| 可読性 | 単純な処理に強い | 入れ子構造や分割統治に強い |
| 限界 | 特になし | 深すぎるとスタックオーバーフロー |
👉 結論:
- 単純な繰り返し → ループ
- 入れ子構造や分割統治 → 再帰


