代码之家  ›  专栏  ›  技术社区  ›  sebhofer

管理/清理多个缓存

  •  0
  • sebhofer  · 技术社区  · 6 年前

    我在做一个复杂的计算 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 回复  |  直到 6 年前
        1
  •  1
  •   Aaron M. Eshbach    6 年前

    我建议使用比 ConcurrentDictionary 以便指定过期策略。 Here's one on FSSnip 那包裹着 并发字典 并允许基于时间的过期,但可以根据其他条件添加过期。这样你就可以使用 memoizeWithExpiration 不用担心电话那边的清理工作。

        2
  •  1
  •   AMieres    6 年前

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

    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 函数自动memoize函数可以执行此操作,如下所示:

    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())
    

    这也将允许您单独清除它们或使用某些条件,如按模块等。