我正在执行复杂的计算(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,当然可以将所有缓存收集到一个列表中。但是我必须把字典装箱,对我来说似乎不太好。有更好的(整体)策略吗?
答案 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())
还可以让您单独清除它们,或使用某些条件(例如按模块等)清除它们。