# \[ANN\] Memoization.jl

**URL:** <https://discourse.julialang.org/t/ann-memoization-jl/31556>\
**Category:** Package Announcements\
**Tags:** memoize\
**Created:** [November 27, 2019, 2:49am UTC](https://discourse.julialang.org/t/ann-memoization-jl/31556 "2019-11-27T02:49:01Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![marius311](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marius311/32/3953_2.png) [@marius311](https://discourse.julialang.org/u/marius311)\
**Post date:** [November 27, 2019, 2:49am UTC](https://discourse.julialang.org/t/ann-memoization-jl/31556/1 "2019-11-27T02:49:01Z")

</div>

I created [Memoization.jl](https://github.com/marius311/Memoization.jl) to address some of the limitations of [Memoize.jl](https://github.com/JuliaCollections/Memoize.jl). It’s API compatible with Memoize.jl (just `@memoize` your function definitions):

```julia

julia> using Memoization

julia> @memoize f(x) = (println("Computed $x"); x)

julia> f(2)
Computed 2
2

julia> f(2)
2

```

As of this writing, Memoization.jl has the following advantages:

- It allows more function definition forms, including with keyword arguments and type parameters.

- It does not issue any warnings, and allows you to memoize different methods of the same function across different modules.

- Closures work, meaning different instances of closures with different closed-over variables can be separately and simultaneously memoized.

- You can empty memoization caches.

- Lookup is a bit faster

Feel free to take it for a spin and let me know if you run into any issues!

---

<div class="post-metadata">

**Author:** ![xiaodai](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xiaodai/32/15937_2.png) [@xiaodai](https://discourse.julialang.org/u/xiaodai)\
**Post date:** [November 27, 2019, 2:53am UTC](https://discourse.julialang.org/t/ann-memoization-jl/31556/2 "2019-11-27T02:53:52Z")

</div>

eh… so you guys can’t agree on how to combine the two into one package?

---

<div class="post-metadata">

**Author:** ![marius311](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marius311/32/3953_2.png) [@marius311](https://discourse.julialang.org/u/marius311)\
**Post date:** [November 27, 2019, 3:08am UTC](https://discourse.julialang.org/t/ann-memoization-jl/31556/3 "2019-11-27T03:08:43Z")

</div>

No, I just made no attempt to combine the packages or submit a PR into that one since its just a 100% rewrite.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [November 27, 2019, 7:37am UTC](https://discourse.julialang.org/t/ann-memoization-jl/31556/4 "2019-11-27T07:37:20Z")

</div>

> [@xiaodai](#):
>
> eh… so you guys can’t agree on how to combine the two into one package?

I think that remarks like this are unwarranted. It is perfectly fine to develop a new package for something that already exists, especially if it is a complete rewrite.

The package ecosystem benefited a lot from people exploring new ways of doing something. Eventually parallel approaches may get merged, or develop a common API, but it is also OK to just have slightly parallel or overlapping functionality.

---

<div class="post-metadata">

**Author:** ![StevenSiew](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevensiew/32/218393_2.png) [@StevenSiew](https://discourse.julialang.org/u/StevenSiew)\
**Post date:** [November 27, 2019, 9:13am UTC](https://discourse.julialang.org/t/ann-memoization-jl/31556/5 "2019-11-27T09:13:49Z")

</div>

Marious311, kindly inform your audience on the information page of your package if your [Memoization.jl](https://github.com/marius311/Memoization.jl) is thread safe for use in multi-threading julia-1.3

Thank you

---

<div class="post-metadata">

**Author:** ![marius311](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marius311/32/3953_2.png) [@marius311](https://discourse.julialang.org/u/marius311)\
**Post date:** [November 27, 2019, 9:40am UTC](https://discourse.julialang.org/t/ann-memoization-jl/31556/6 "2019-11-27T09:40:32Z")

</div>

Good question, the answer is it is not threadsafe with either the default `IdDict` nor with `Dict`, I can update the docs.

If we had a `ThreadSafeDict` data type (to my knowledge this doesn’t currently exist in Julia, although [ThreadSafeDataStructures.jl](https://github.com/JuliaCollections/ThreadSafeDataStructures.jl) was on the right path), then `@memoize ThreadSafeDict f(x) = ...` should already be threadsafe for top-level functions with no changes to this package (and it could made threadsafe for closures too with some minor tweaks).

---

<div class="post-metadata">

**Author:** ![Tomas\_Pevny](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomas_pevny/32/25466_2.png) [@Tomas\_Pevny](https://discourse.julialang.org/u/Tomas_Pevny)\
**Post date:** [November 27, 2019, 10:04am UTC](https://discourse.julialang.org/t/ann-memoization-jl/31556/7 "2019-11-27T10:04:09Z")

</div>

Have you thought about adding an option to save the content to disk instead to some dictionary?

---

<div class="post-metadata">

**Author:** ![antoine-levitt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/antoine-levitt/32/4008_2.png) [@antoine-levitt](https://discourse.julialang.org/u/antoine-levitt)\
**Post date:** [November 27, 2019, 7:48pm UTC](https://discourse.julialang.org/t/ann-memoization-jl/31556/8 "2019-11-27T19:48:05Z")

</div>

The annoying warnings with precompilation are gone! Thanks!

---

<div class="post-metadata">

**Author:** ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)\
**Post date:** [November 27, 2019, 7:57pm UTC](https://discourse.julialang.org/t/ann-memoization-jl/31556/9 "2019-11-27T19:57:34Z")

</div>

> [@Tomas\_Pevny](#):
>
> Have you thought about adding an option to save the content to disk instead to some dictionary?

It probably wouldn’t be crazy hard to build some sort of `MmappedDict` which could be pluggable into this package.

---

<div class="post-metadata">

**Author:** ![ericphanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ericphanson/32/215186_2.png) [@ericphanson](https://discourse.julialang.org/u/ericphanson)\
**Post date:** [November 27, 2019, 8:18pm UTC](https://discourse.julialang.org/t/ann-memoization-jl/31556/10 "2019-11-27T20:18:23Z")

</div>

Just to say that there are some more memoization packages listed here: [[ANN] Caching.jl, yet another memoizer with more features](https://discourse.julialang.org/t/ann-caching-jl-yet-another-memoizer-with-more-features/21565), and Caching.jl mentions disk support.

---

<div class="post-metadata">

**Author:** ![marius311](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marius311/32/3953_2.png) [@marius311](https://discourse.julialang.org/u/marius311)\
**Post date:** [November 27, 2019, 8:45pm UTC](https://discourse.julialang.org/t/ann-memoization-jl/31556/11 "2019-11-27T20:45:30Z")

</div>

> [@Mason](#):
>
> It probably wouldn’t be crazy hard to build some sort of `MmappedDict` which could be pluggable into this package.

Yea I think that’d be the right approach. It _almost_ already works with the output of e.g. `jldopen` which returns a Dict-like thing. I will play with it.

> [@ericphanson](#):
>
> Just to say that there are some more memoization packages listed here: [[ANN] Caching.jl, yet another memoizer with more features ](https://discourse.julialang.org/t/ann-caching-jl-yet-another-memoizer-with-more-features/21565), and Caching.jl mentions disk support.

Thanks for pointing that out, I wasn’t aware of either Caching.jl or Anamnesis.jl linked there, both of which have some complimentary features like disk caching which are really nice. One thing which appears to be unique to this package is that it doesn’t change your function’s name or return instead a non-function object, which is what lets this package memoize on a per-method basis.

---

<div class="post-metadata">

**Author:** ![dilumaluthge](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dilumaluthge/32/29283_2.png) [@dilumaluthge](https://discourse.julialang.org/u/dilumaluthge)\
**Post date:** [November 30, 2019, 2:09am UTC](https://discourse.julialang.org/t/ann-memoization-jl/31556/12 "2019-11-30T02:09:33Z")

</div>

Great package, thanks for sharing!

---

<div class="post-metadata">

**Author:** ![marius311](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marius311/32/3953_2.png) [@marius311](https://discourse.julialang.org/u/marius311)\
**Post date:** [April 16, 2021, 9:41pm UTC](https://discourse.julialang.org/t/ann-memoization-jl/31556/13 "2021-04-16T21:41:20Z")

</div>

Quick update as I just tagged a new version (0.1.6) that addresses one limitation this package had. Previously, if you wanted to e.g. use a `ThreadSafeDict` as a cache, you had to load the package `ThreadSafeDicts` _before_ `Memoization` otherwise you got a world-age error. This is now no longer required, you can load packages in any order you like.

Since I wrote this package, Memoize.jl has improved so I think the main remaining differences / advantages of this package are that:

- It can memoize closures and callable objects.
- The memoization cache for a given function is all stored in a single place, and can be emptied with `Memoization.empty_cache!(func)` regardless of which module the definition and the call are in.
- All the caches for every function/closure/callable are stored in one place, `Memoization.caches`, and there is also `Memoization.empty_all_caches!()` to clear everything.

If none of these are an issue for you, the two packages continue to be basically drop-in replacements for eachother. Happy memoizing!
