# When to use Once for memoization?

While watching Stephen Wolfram's twitch stream I saw him use Once for memoization, which surprised me since I thought of Once as a kind of general purpose Needs. It is quite slow compared to the usual memoization pattern

f[0] = f[1] = 1;
f[x_] := Once[f[x - 1] + f[x - 2]];

g[0] = g[1] = 1;
g[x_] := g[x] = g[x - 1] + g[x - 2];

Timing[f[1000];]
(* {0.518758, Null} *)

Timing[g[1000];]
(* {0.003621, Null} *)


However, I was wondering if anyone else has found situations where this method is useful, perhaps for memoization with a persistence beyond the current kernel session (using the ExpirationDate or PersistenceTime options).

• See here for an example of using Once together with classical memoization to achieve the best of both: speed and persistence. – Roman Jun 11 '19 at 18:41

If your goal is maximum performance in a kernel session, Once is never the answer. It is just too heavyweight. It does, however, provide a real memoization method--we're still talking about sub-second evaluation, for a computation that wouldn't complete without--that is perhaps easier to read for non-experts. And if each step in the computation is expensive, the overhead of Once is negligible.
Since Once supports storing the results outside the current kernel session (e.g, local files), I could see it being used to memoize expressions where the cost of computing them is much greater than the cost of writing them to file. That way you could concievably save your memoization accross kernel restarts. I've never tried this, though.