【めもか】

メモ化 とは?

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

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

📌 このページのポイント
fib(5):計算した結果をメモする メモ化なしメモ化ありfib(5)fib(4)fib(3)fib(3)fib(2)引数と結果fib(0) → 0fib(1) → 1fib(2) → 1fib(3) → 2fib(4) → 3fib(5) → 5重複する部分計算本体実行 15回本体実行 6回木の一部を省略0〜5を1回ずつ次はメモを利用fib(5)5再計算せず同じ引数保存結果保存する容量と更新の条件も考える
fib(0)=0、fib(1)=1とする単純な再帰で、空のキャッシュからfib(5)を1回求めた例です。15回・6回は関数本体の実行回数で、キャッシュの照会回数や速度の倍率ではありません。左の木は一部を省略しています。
ひよこ ひよこ
キャッシュとメモ化の違いは?
ペンギン先生 ペンギン先生
メモ化は「関数の引数→結果」の対応を記憶するキャッシュ手法だよ。キャッシュ全体には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(メモ・覚え書き)から派生。計算結果をメモしておいて再利用するよ

参考資料

← 用語集にもどる