在Julia中的函数内本地化memoization

时间:2015-11-18 07:52:10

标签: julia memoization

有没有办法在函数内本地化memoization(通过Memoize.jl)?或者至少删除memoization创建的词典?

澄清:假设我定义了一个函数f(x,y)。我想从一个新的表开始,为y的每个新值。也就是说,假设y = y0,f(。,y0)对x,x-1等进行迭代,但是给定一个新的y = y1,我不需要为y0存储旧表,所以内存可以被释放。我怎么能这样做?

解决方案:

cachedfib() = begin
    global dict = Dict()
    global dict2 = Dict()
    function _fib(n::Int, a::Int)
        if !haskey(dict2, a)
            dict2[a] = true
            dict = Dict()
        end
        if haskey(dict, (n, a))
            return dict[(n, a)]
        elseif n < 2
            dict[(0, a)] = 0
            dict[(1, a)] = 1
            return dict[(n, a)]
        else
            dict[(n, a)] = a*(_fib(n - 1, a) + _fib(n - 2, a))
            return dict[(n, a)]
        end
    end
end
fib = cachedfib()

fib(10, 1)
fib(10, 2)

现在调用dictdict2并检查每次第二个参数更改时是否刷新字典。当要存储的参数是整数并且使用Array而不是Dict

时,您可以获得更好的性能

2 个答案:

答案 0 :(得分:4)

let Aold = nothing
global foo
function foo(A::AbstractArray)
    if A == Aold
        println("Same as last array")
    else
        Aold = A
    end
    nothing
end
end

结果:

julia> A = rand(2,2)
2x2 Array{Float64,2}:
 0.272936  0.153311
 0.299549  0.703668

julia> B = rand(2,2)
2x2 Array{Float64,2}:
 0.6762    0.377428
 0.493344  0.240194

julia> foo(A)

julia> foo(A)
Same as last array

julia> foo(B)

julia> foo(A)

julia> foo(A)
Same as last array

julia> Aold
ERROR: UndefVarError: Aold not defined

答案 1 :(得分:3)

要使用memoization技术,您可以使用let或闭包。看看我factorial的快速实现(带闭包)。

with_cached_factorial() = begin
    local _cache = [1] #cache factorial(0)=1    
    function _factorial(n)          
        if n < length(_cache) 
            println("pull out from the cache factorial($n)=$(_cache[n+1])")
            _cache[n+1]
        else
            fres =  n * _factorial(n-1)
            push!(_cache, fres)
            println("put factorial($n)=$fres into the cache of the size=$(sizeof(_cache))") #a
            fres            
        end
    end 
end

现在,只需使用它:

julia> myf = with_cached_factorial()
_factorial (generic function with 1 method)

julia> myf(3)
pull out from the cache factorial(0)=1
put factorial(1)=1 into the cache of the size=16
put factorial(2)=2 into the cache of the size=24
put factorial(3)=6 into the cache of the size=32
6

julia> myf(5)
pull out from the cache factorial(3)=6
put factorial(4)=24 into the cache of the size=40
put factorial(5)=120 into the cache of the size=48
120

julia> myf(10)
pull out from the cache factorial(5)=120
put factorial(6)=720 into the cache of the size=56
put factorial(7)=5040 into the cache of the size=64
put factorial(8)=40320 into the cache of the size=72
put factorial(9)=362880 into the cache of the size=80
put factorial(10)=3628800 into the cache of the size=88
3628800