Clojure的“memoize”函数在缓存慢速sql查询和复杂计算时是否有用?

时间:2016-10-27 15:12:13

标签: caching clojure pure-function

我的项目有一个mysql数据库和一个由Clojure编写的后端。

数据库的某些表每天只更新一次,以查询最新的 我们将使用的信息。

可是:

  1. 数据库非常大,网络速度慢,所以每个查询都会 需要几秒钟。

  2. 我们需要在每次查询后进行复杂的计算。

  3. 我们需要进行多种sql查询,因此保存每个sql查询的结果是不现实的。

  4. 我们需要经常更改计算功能 调试的目的。

  5. 在sql查询速度慢的情况下,现在所有事情都太慢了。

    幸运的是,我们的数据每天只会更新一次,而且数据库中的一些查询经常被使用。

    所以我们想要缓存常用的sql查询和中间结果。

    Clojure的memoize功能对这类工作有用吗?我担心sql查询不纯,所以memoize不应该缓存他们的结果。但是有一天我们的sql查询结果必须相同。

    我可以在一天内memoize结果并在第二天自动更新结果吗?

    感谢您的帮助!

1 个答案:

答案 0 :(得分:6)

你应该使用缓存,例如: G。 clojure.core.cache。

澄清注释:memoization有助于纯函数:如果你的函数在给定相同输入的情况下总是返回相同的输出,你可以在计算一次后存储它。

如果输出随时间变化,则需要进行失效。带有失效的记忆(以及一些其他问题,例如记忆事物的大小)被称为"缓存"。

如果使用memoization机制进行缓存,那么您实际执行的操作就是在其上实现缓存。使用缓存库的工作要少得多。

在这种情况下,您需要在午夜和#34;执行类似"失效的操作。有关如何执行此操作的说明,请参阅https://github.com/clojure/core.cache/wiki

编辑:它可能看起来像这样(未经测试,带上你自己的today):

(defcache MidnightCache [cache dates]
  CacheProtocol
  (lookup [this key]
    (lookup this key nil))
  (lookup [this key not-found]
    (if (has? this key)
      (get cache key)
      not-found))
  (has? [this key]
    (let [d (get dates key)]
      (and d
           (= d (today)))))
  (hit [this key]
    this)
  (miss [this key new-value]
    (MidnightCache. (assoc (dissoc cache key)
                           key new-value)
                    (assoc (dissoc dates key)
                           key (today))))
  (evict [this key]
    (MidnightCache. (dissoc cache key)
                    (dissoc dates key)))
  (seed [this base]
    (MidnightCache. base
                    (zipmap (keys base)
                            (iterate identity (today))))))