我正在使用 core.cache,想知道为什么带有大阈值且无初始化数据的 lru 缓存创建耗时如此之久。
(require '[clojure.core.cache.wrapped :as cw])
(time (cw/lu-cache-factory {} :threshold 10000000))
瓶颈似乎在这一行,其中 lru 列表被填充了假值。我查看了 LRUCache 代码,并看不到 lru 列表不应自然增长而只初始化基本值的理由。我还测试了带更简单的初始化函数的 LRUCache
(defn- build-leastness-queue
[base start-at]
(into (clojure.data.priority-map/priority-map) (for [[k _] base] [k start-at])))
并且所有 LRUCache 测试仍然通过。
原始的 build-leastness-queue
也在 LUCache 中使用,使用新版本时测试不再通过。在尝试让修改后的版本也能在 LUCache 中工作的时候,我发现它目前有点出问题。
(require '[clojure.core.cache :as c])
(def ca (c/lu-cache-factory {:a 1 :b 2} :threshold 2))
(-> ca
(assoc :c 3)
.lu)
;; => {:a 0, :c 1}
(-> ca
(dissoc :a)
(assoc :c 3)
.lu)
;; => {:c 0, :b 0}
因此,在当前实现中,新关联(未命中)的项目的 LU 优先级取决于 lu 缓存当前是否已满。
我今早签署了 Clojure CA,想问问是否能有人把我添加到 JIRA,这样我就可以提议修补这些问题(那里的名字是 FiVo)。
关于 LUCache 的语义还有一个问题。测试中包含这样的注释 确保测试结果不依赖于数量上的任意赢者决定,但看起来它确实依赖于任意的赢者决定
(def ca (c/lu-cache-factory {:a 1} :threshold 2))
(-> ca
(assoc :b 2)
(assoc :c 3)
(assoc :d 4))
;; => {:b 2, :d 4}
后来的关联项应该有更高的优先级吗?这将使补丁变得更加复杂,我强烈倾向于保持任意的赢者决定。