メモ化と呼ばれる最適化技法について説明した優れた記事がいくつかあります。 こことここからアクセスできます。 これから行うのは、メモ化とは何かについての簡単な概要です。 さらに、「メモ化」したコードが実際に何をしているのか、1行ずつ解析していきます。 この記事の終わりまでには、メモ化を完全に理解できるでしょう。

メモ化は、長い再帰/反復関数をより速く実行させるためのプログラム的なプラクティスです。 メモ化された関数に同じ値を入力すると、関数を再度実行する代わりに、キャッシュに格納された値が返され、パフォーマンスが向上します。 もはやプログラムは、結果を得るためにすべての数値を再計算する必要はありません。

素晴らしい響きでしょう?

ここで、基本的な memo 関数の例を挙げます。

最初から始めましょう。 この無名クロージャは、任意の変数またはこの場合、memo に渡された関数を継承することができます。

補足: すべての関数が引数オブジェクトを持っているなら、なぜ私たちは memo の引数オブジェクトを継承しないのでしょうか。 それは、ルールとして、クロージャは外部関数の引数オブジェクトを継承しないからです。 メモ化したい関数で遊ぶために、このルールを利用します。

非常に単純で非実用的な例を見て、メモ化が何をしているかを正確に分解してみましょう。 ところで、このコード、あるいは、どのようなコードでも、それがどのように動作するかを実際に感じるためにコピー/貼り付けする必要があります。 事実上、それ自体が語っています。 メモ関数が何をしているかを分解したので、関数式を作成し、memo に再帰的なフィボナッチ関数を渡して、何が起こるか見てみましょう。

//Now we'll test our code!
// =======TEST=======
fib(10)//On the first try we need to load//=> loading…//=> loading…//=> loading…//=> loading…//=> loading…//=> 4 loadings later we get...//=> 89// And on the second try…fib(10)//=> 89//No loading! Yaay!//The cool thing about memoizing the recursive Fibonacci algorithm is that once we make a call for the value of the nth number in the series, we are able to store all the previous numbers in the series.//So if we try...
fib(7) //=> 21
//We don't have to recalculate anything.//And if we want to try fib(11)...
fib(11)
//loading...
//=> 144
//Our memoized recursive function already cached fib(1-10),so all it needed to do was to calculate the cached values. // This is what the cache now looks like:
/*
{ '{"0":0}': 1,
'{"0":1}': 1,
'{"0":2}': 2,
'{"0":3}': 3,
'{"0":4}': 5,
'{"0":5}': 8,
'{"0":6}': 13,
'{"0":7}': 21,
'{"0":8}': 34,
'{"0":9}': 55,
'{"0":10}': 89,
'{"0":11}': 144}
*/

結論

キーと値のペアに煮詰めると、メモ化が神秘的になります。 私たちが行っているのは、オブジェクトを作成し、ユーザー入力に一致する既存の値をチェックし、オブジェクトに存在しない場合は新しいキーと値のペアを保存することだけです。

もちろん、このデータをすべて保存することは、メモリを使用することになります。 メモ化を実装するのは、純粋で、重い反復計算を伴う関数にするのが最善です。

コメントを残す

メールアドレスが公開されることはありません。