Clojure - 在磁盘上记忆

时间:2015-07-02 14:05:08

标签: caching clojure memoization

我想提高返回调整大小的图像的函数的性能。请求的图像大小不应该变化很大(取决于设备),因此以某种方式缓存结果是有意义的。

我当然可以将它存储在磁盘上,并检查调整大小的图像是否存在,并确保如果原始图像被删除,调整后的版本也是......

或者,我可以使用memoized功能。但由于结果可能很大(我认为图像大约为5-10 MB),将它们存储在内存中是没有意义的(几十GB图像及其修改后的版本会填满内存)很快)。

那么,有没有办法让一个memoized函数像常规Clojure coefplot Domestic Foreign , xtitle(Mpg) xline(`r(mean)') /// groups(Three Four Five = "Repair Record 1978") 一样,但是由本地磁盘中的文件夹而不是内存支持?然后我可以使用defmemo策略来确保图片不会长时间不同步。

类似于crache,但由文件系统支持?

3 个答案:

答案 0 :(得分:3)

不要过分思考它。您的文件系统作为缓存是正确的想法。如果一个文件受欢迎并且文件被大量访问,那么您的操作系统将确保它在RAM中。这与许多数据库使用的策略相同。例如,Elasticsearch要求您留下足够的RAM以将Lucene索引文件放在RAM中。

也不要修改你的文件!以功能方式执行:将它们视为不可变数据。您的输入文件不应更改。如果是,那么它就是一个新文件。硬盘空间越来越便宜。不要害怕周围有很多文件。如果必须,您可以进行垃圾收集,在一段时间后删除旧的/已标记的文件。

要查看文件是否在缓存中,您只需检查文件是否存在。如果它不是:你写一次。

总结一下:

  • 让你的操作系统工作缓存
  • 不要编辑您的文件。将它们视为不可变数据。写一次
  • 您的操作系统将释放未使用文件的RAM。硬盘空间非常便宜。

答案 1 :(得分:2)

为什么不从clojure.core.cache实现TTL-Cache,用你需要的功能包装它?您的密钥可以是标识已调整大小的图像的任何值,其值将是它在磁盘上的位置。然后你可以实现某种get-or-set!函数,传递它将被调用的函数,当它不存在时生成图像。 e.g。

(def Cache (atom (cache/ttl-cache-factory {} :ttl 20000)))

(defn get-or-update!
  "wraps the recommended has-hit-get pattern
   https://github.com/clojure/core.cache/wiki/Using"
  [key fn]
  (if (cache/has? @Cache key)
    (get (swap! Cache #(cache/hit % key)) key)
    (get (swap! Cache #(cache/miss % key (fn))) key)))

答案 2 :(得分:1)

你需要的东西听起来像是Datomic的完美用途。它很容易从Clojure中使用,非常高效,就像任何好的DB一样,它在内存中最近使用(LRU)缓存。它还可以使用各种各样的后备数据库作为基板,从严格的内存(最适合测试和实验)到Postgres,Redis,DynamoDB,Riak等。还有一个使用本地文件的“开发”模式对于所有存储。

请在此处查看所有详细信息:

标准版本具有适用于大多数用途的免费永久许可证。对于高级功能,可以使用付费版本。