# Saving memoization to disk

I like using memoization (i.e. the construct myFunction[x_]:=myFunction[x]=...) when I have a heavy function that I need to re-evaluate on the same arguments. However, I find it frustrating that each time I quit the kernel(s), all the advantage goes lost.

Is there a way of saving the results? I can think of a very cumbersome way of doing it, such as this block upon defining our function

memo = If[FileExistsQ[FileNameJoin[{Directory[], "memo.mx"}]], Import["memo.mx"], {}];
myFunction[x_] := Module[{value = ...},
AppendTo[memo, "myFunction[" <> ToString[x] <> "]=" <> ToString[value]];
Export["memo.mx", Union@memo];
myFunction[x] = value]
Evaluate[ToExpression/@memo];


Is this okay, or is there a better (or even designated) way of doing this?

• And DumpSave? Feb 19, 2015 at 17:16
• I guess that does it! (I'm checking) Feb 19, 2015 at 17:17
• Yes! Thank you :D Feb 19, 2015 at 17:22
• @unlikely Can you post an answer? Feb 19, 2015 at 17:43
• Here's a solution using Once to construct persistent memoization. Mar 19, 2021 at 7:59

Not much different from your approach and maybe not the best/safest approach, but DumpSave helps a bit because at least you don't have to works with strings:

cacheFile = FileNameJoin[{\$TemporaryDirectory, "fibonacciCache" <> ".mx"}];
If[FileExistsQ[cacheFile],
Get[cacheFile],
fibonacci[1] = 1;
fibonacci[2] = 1;
fibonacci[n_Integer] := Module[{},
fibonacci[n] = fibonacci[n - 1] + fibonacci[n - 2];
DumpSave[cacheFile, fibonacci];
fibonacci[n]
]
]


For example

In[3]:= fibonacci[500] // Timing

Out[3]= {0.562500, \ 1394232245616978801397243828704072839500702565876973072641089629483255\ 71622863290691557658876222521294125}

Now Quit[]-ing and reevaluating the previous cell:

In[3]:= fibonacci[500] // Timing

Out[3]= {0., \ 1394232245616978801397243828704072839500702565876973072641089629483255\ 71622863290691557658876222521294125}

Here is another approach with LocalSymbol:

PersistentMemoize[key_, expr_] := Module[{name, value},
name = "PersistentMemoize/" <> ToString[key // Hold // InputForm];
value = LocalSymbol[name];
value = LocalSymbol[name] = expr;
];
value
];
SetAttributes[PersistentMemoize, HoldAll];

ClearPersistentMemoization[] := DeleteObject[LocalObjects["LocalSymbols/PersistentMemoize"]];

(* example *)

fib[n_] := fib[n] = PersistentMemoize[fib[n],
Print["computing fib[" <> ToString[n] <> "]..."];
fib[n - 1] + fib[n - 2]
];
fib[1] = 1;
fib[2] = 2;
$$$$
`
• Actually, after writing this answer, a further search leads me to an answer that looks nicer. Mar 19, 2021 at 8:17