【めもか】

メモ化 とは?

最終更新:
💡 計算結果を「メモして」使い回す

関数の引数と計算結果の対応を記憶し、同じ入力への結果を再利用して再計算を省く最適化手法。結果が変わる条件やキャッシュの寿命も考える。

📌 このページのポイント
fib(5)の重複計算を減らす メモ化なし メモ化あり fib(5) fib(4) fib(3) fib(3) fib(2) 同じ部分計算が重複 本体実行:15回 木の一部は省略 引数 → 結果を記憶 fib(0) → 0 fib(1) → 1 fib(2) → 1 fib(3) → 2 fib(4) → 3 fib(5) → 5 本体実行:6回 0〜5の各結果を1回計算 次に同じ引数なら、保存した結果を使う
fib(0)=0、fib(1)=1。空のキャッシュからfib(5)を一度求める例。本体実行回数はキャッシュへのアクセス回数や処理時間ではない。
ひよこ ひよこ
キャッシュとメモ化の違いは?
ペンギン先生 ペンギン先生
メモ化は「関数の引数→結果」の対応を記憶するキャッシュ手法だよ。キャッシュ全体にはHTTPの応答保存なども含まれる。同じ入力から同じ結果が得られる計算なら使いやすいけれど、時刻や外部データで結果が変わるなら、いつ捨てるかも考える必要があるんだ
ひよこ ひよこ
フィボナッチ数列での効果は?
ペンギン先生 ペンギン先生
fib(0)=0、fib(1)=1、fib(n)=fib(n−1)+fib(n−2)という例では、素朴な再帰は同じ部分計算を繰り返すよ。メモ化で各nの結果を保持すれば、足し算を一定時間とみなす分析ではO(n)の計算にできる。大きな整数の計算コストや再帰の深さは別に考えよう
ひよこ ひよこ
図の15回と6回は何を数えているの?
ペンギン先生 ペンギン先生
fib(5)を空のキャッシュから一度求めるときの、関数本体を実行する回数だよ。メモ化なしは15回、ありはfib(0)からfib(5)の6種類を各1回。キャッシュへアクセスする呼び出しの回数や処理時間そのものとは違うんだ
ひよこ ひよこ
Reactのメモ化も同じ?
ペンギン先生 ペンギン先生
useMemoは依存値を比較して計算結果を再利用し、memoは同じpropsでの親からの再レンダリングを省くために使うよ。ただし自身のstateや利用するcontextの変更では描画されるし、キャッシュが捨てられる場合もある。正しさをメモ化の有無に頼らないことが大切だね
ひよこ ひよこ
どの関数もメモ化すれば速くなる?
ペンギン先生 ペンギン先生
効果が小さい計算や入力が毎回違う処理では、保存や検索の負担が増えることもあるよ。書き込みなど毎回行うべき副作用も省いてはいけない。必要な部分を測定して選び、保存が増えるなら件数上限や破棄方法を設けよう。LRUは最近使った結果を残す方法の一つだね
ペンギン
まとめ:ざっくりこれだけ覚えればOK!
「メモ化」って出てきたら「同じ入力の計算結果をメモして使い回す最適化」と思えばだいたいOK!
📖 おまけ:英語の意味
「Memoization」 = メモ化
💬 Memo(メモ・覚え書き)から派生。計算結果をメモしておいて再利用するよ

参考資料

← 用語集にもどる