管理/清理多个缓存

时间:2018-10-15 10:31:47

标签: caching f#

我正在执行复杂的计算(Markov chain model

let memoize f =
    let cache = new ConcurrentDictionary<'key,'value>()
    cache, fun x -> cache.GetOrAdd(x, Func<'key, 'value>f)

缓存多个功能的中间结果。总体结构是这样的

module Foo =
    [...]
    let _, foo' = memoize foo

module Bar =
    [...]
    let _, bar' = memoize bar 

module Main = 
    open Foo
    open Bar
    [...]
    let result =
        foobar (foo' a) (bar' b)

通常我运行一次,然后程序终止,但是不清理那些缓存字典显然不好。另外,有时我需要为许多不同的输入调用模型,然后很快遇到内存问题。一次清除多个缓存的最佳方法是什么?

修改

评论中提到的A,当然可以将所有缓存收集到一个列表中。但是我必须把字典装箱,对我来说似乎不太好。有更好的(整体)策略吗?

2 个答案:

答案 0 :(得分:1)

我建议使用比ConcurrentDictionary更健壮的缓存结构,以便您可以指定过期策略。 Here's one on FSSnip包装ConcurrentDictionary并允许基于时间的到期,但是您可以根据其他条件添加到期。这样一来,您只需使用memoizeWithExpiration,而不必担心在调用方进行清理。

答案 1 :(得分:1)

这是我的建议,简单有效:

module Foo =
    [...]
    let fcache, foo' = memoize foo

module Bar =
    [...]
    let bcache, bar' = memoize bar

module Main = 
    open Foo
    open Bar
    let clearCaches = [
        fcache.Clear
        bcache.Clear
    ]
    [...]
    let result =
        foobar (foo' a) (bar' b)
    let clearAll() =
        clearCaches  |> Seq.iter (fun clear -> clear())

更新

如果您想自动收集clear函数,则备忘函数可以做到这一点,就像这样:

let clearCaches = Dictionary<_,_>()

let memoize (name:string) f =
    let cache = new ConcurrentDictionary<'key,'value>()
    clearCaches.Add(name, cache.Clear)
    fun x -> cache.GetOrAdd(x, Func<'key, 'value>f)

module Foo =
    [...]
    let foo' = memoize "Foo.foo" foo

module Bar =
    [...]
    let bar' = memoize "Bar.bar" bar

module Main = 
    open Foo
    open Bar
    [...]
    let result =
        foobar (foo' a) (bar' b)

    let clearAll() =
        clearCaches  |> Seq.iter (fun kvp -> kvp.Value())

还可以让您单独清除它们,或使用某些条件(例如按模块等)清除它们。