使用缓存而不是记忆来加速功能

时间:2018-08-28 08:50:13

标签: julia

虽然记住一个功能是个好主意,但它可能会导致程序崩溃,因为该程序可能会耗尽内存。

因此,在生产程序中不能使用安全选项。

相反,我开发了具有固定内存插槽的缓存,软内存限制和硬内存限制在下面。当缓存插槽超过硬限制时,它将删除使用最少的插槽,直到插槽数量减少到软限制为止。

struct cacheType
    softlimit::Int
    hardlimit::Int
    memory::Dict{Any,Any}
    freq::Dict{Any,Int}
    cacheType(soft::Int,hard::Int) = new(soft,hard,Dict(),Dict())
end

function tidycache!(c::cacheType)
    memory_slots=length(c.memory)
    if memory_slots > c.hardlimit
        num_to_delete = memory_slots - c.softlimit
        # Now sort the freq dictionary into array of key => AccessFrequency
        # where the first few items have the lowest AccessFrequency
        for item in sort(collect(c.freq),by = x -> x[2])[1:num_to_delete]
            delete!(c.freq, item[1])
            delete!(c.memory, item[1])
        end
    end
end

# Fibonacci function  
function cachefib!(cache::cacheType,x)
    if haskey(cache.memory,x)
        # Increment the number of times this key has been accessed
        cache.freq[x] += 1
        return cache.memory[x]
    else
        # perform housekeeping and remove cache entries if over the hardlimit
        tidycache!(cache)
        if x < 3
            cache.freq[x] = 1
            return cache.memory[x] = 1
        else
            result = cachefib!(cache,x-2) + cachefib!(cache,x-1)
            cache.freq[x] = 1
            cache.memory[x] = result
            return result
        end
    end
end

c = cacheType(3,4)
cachefib!(c,3)
cachefib!(c,4)
cachefib!(c,5)
cachefib!(c,6)
cachefib!(c,4)
println("c.memory is ",c.memory)
println("c.freq is ",c.freq)

我认为这在生产环境中最有用,而不是仅使用没有内存消耗限制的内存,否则可能导致程序崩溃。

在Python语言中,它们具有

@ functools.lru_cache(maxsize = 128,typed = False)

装饰器将带有回忆的可调用包装的函数包装起来,最多可保存最新调用的最大大小。当使用相同的参数定期调用昂贵的或I / O绑定的函数时,可以节省时间。

由于使用字典来缓存结果,因此该函数的位置和关键字参数必须是可哈希的。

朱莉娅语有同等语言吗?

1 个答案:

答案 0 :(得分:0)

LRUCache.jl,它提供的LRU类型基本上像Dict。不幸的是,这似乎不适用于Memoize.jl包,但是您可以使用my answer to your other question

using LRUCache

const fibmem = LRU{Int,Int}(3) # store only 3 values
function fib(n)
    get!(fibmem, n) do
        n < 3 ? 1 : fib(n-1) + fib(n-2)
    end
end