2024 Clojure 状态调查!中分享您的想法。

欢迎!请查看关于页面以了解如何使用本站更多信息。

+3
core.cache

我在与LazyMap结合使用core.cache。懒惰映射类似于映射类型的对象(封装映射并添加一些逻辑以自动强制延迟与键关联的值的新数据类型)。

当我开始将懒惰映射作为 FIFO 缓存的值时,我注意到所有值都是在映射进入缓存后立即被实现的。经过一些调查,我发现这是由 clojure.core.cache.wrapped/lookup-or-miss 中的表达式 (= ::expired v)引起的。

内部,=会调用clojure.lang.Util/equiv(因为LazyMap实现了IPersistentCollection),然后经过一些分配后,equiv被调用以检查懒惰映射的内容是否与其他对象(隐含为其他映射)相等。这是期望的行为,懒惰映射实现所有值以使比较成为可能。

然而,当比较类似映射的对象与不是映射(也不是集合)的东西时,如果在确认确实会返回false的情况下进行短路,那么将受欢迎。但改变这一点可能更多地与 Clojure 本身以及像CLJ-1375一样的事情有关。

如果这样做不会太麻烦,那么在 clojure.core.cache.wrapped 中可以替换的将是

(= ::expired v)(identical? ::expired v)

这不仅将解决像我的这样的边缘情况,还能稍微加快速度(在 Clojure 关键字方面,显式的引用相等棒极了)。

还可能在其他地方进行这种更改的表达式(以防万一)是
(= ::nope ret)(= ::nil v),来自 clojure.core.cache

2 个答案

+1

我不明白为什么将所有这些关键字比较改为identical?检查会存在问题。我会再仔细思考一下,但在此期间,我已经创建了https://clojure.atlassian.net/browse/CCACHE-66

您能提供一个复现示例吗?

谢谢!

以下是一个示例


(require '[clojure.core.cache :as cache]
                 '[clojure.core.cache.wrapped :as cwr]
                 '[lazy-map.core :as lm])

(def C (atom (cache/fifo-cache-factory {})))
(def m (lm/->LazyMap {:a 1 :b (delay 8)}))

m
; => {:a 1, :b <unrealized>}

 (cwr/lookup-or-miss C :k (constantly m))
; => {:a 1, :b 8}

m
; => {:a 1, :b 8}


需要

com.intuitiveexplanations/lazy-map   {:mvn/version "1.0.0"}
org.clojure/core.cache                      {:mvn/version "1.0.225"}
+1

附上了CCACHE-66的补丁

https://gist.github.com/siefca/fa2745999281440867de1d1a89243f6d

(我在大约2或3年前签署了Clojure贡献者协议。)

...