How to do memoization or memoisation in Julia 1.0

前端 未结 3 1620
遇见更好的自我
遇见更好的自我 2021-02-04 15:58

I have been trying to do memorisation in Julia for the Fibonacci function. This is what I came up with.

The original unmodified code (for control purposes)



        
3条回答
  •  小鲜肉
    小鲜肉 (楼主)
    2021-02-04 16:41

    As pointed out in the comments, the Memoize.jl package is certainly the easiest option. This requires you to mark the method at definition time.

    By far the most powerful approach, however, is to use Cassette.jl, which lets you add memoization to pre-existing functions, e.g.

    fib(x) = x < 3 ? 1 : fib(x-2) + fib(x-1)
    
    using Cassette
    Cassette.@context MemoizeCtx
    function Cassette.overdub(ctx::MemoizeCtx, ::typeof(fib), x)
           get(ctx.metadata, x) do
               result = recurse(ctx, fib, x)
               ctx.metadata[x] = result
               return result
           end
       end
    

    A little bit of a description of what is going on:

    • MemoizeCtx is the Cassette "context" which we are defining
    • overdub is run instead of the original function definition
      • We use this to check if the arg exists in the metadata dictionary.
      • recurse(...) tells Cassette to call the function, but ignore the top level overload.

    Now we can run the function with memoization:

    Cassette.overdub(MemoizeCtx(metadata=Dict{Int,Int}()), fib, 80)
    

    Now what's even cooler is that we can take an existing function which calls fib, and memoize the call to fib inside that function:

    function foo()
        println("calling fib")
        @show fib(80)
        println("done.")
    end
    Cassette.overdub(MemoizeCtx(metadata=Dict{Int,Int}()), foo)
    

    (Cassette is still pretty hard on the compiler, so this may take a while to run the first time, but will be fast after that).

提交回复
热议问题