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

欢迎!请参阅关于页面以了解如何使用此服务的一些更多信息。

+3
core.cache

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

当我开始将lazy map作为FIFO缓存中的值时,我发现所有值都是在map被放入缓存后立即实现的。经过一番挖掘,我发现这可能是由于在clojure.core.cache.wrapped/lookup-or-miss中的表达式(= ::expired v)导致的。

实际上,内嵌的=调用会调用clojure.lang.Util/equiv(因为LazyMap实现了IPersistentCollection),然后,在经过一些调度后,equiv会被调用以检查lazy map的内容是否等于其他对象(隐含地是另一个map)。这是期望的行为,lazy map实现所有值以使比较成为可能。

然而,当将类似于map的对象与不是map(或集合)的东西进行比较时,如果我们知道它一定会返回false,那么短路将会受欢迎。但这可能是与Clojure本身以及类似于CLJ-1375的事情更为相关。

如果这不是太大问题,那么可以采取的措施是在clojure.core.cache.wrapped中将

(= ::expired v)替换为(identical? ::expired v)

它不仅可以修复像我这样的角落案例,还可以让事情稍微快一点(当涉及Clojure关键字时,显式的引用等价性真是太棒了)。

可能还需要更改的表达式(以防万一)包括
(= ::nope ret)(= ::nil v)来自clojure.core.cache

2个答案

+1
Fogus 回答了 Mar 3, 2023 by Fogus

我不明白为什么把所有的关键字比较改为 identical? 会成为问题。我会再仔细考虑一下,但与此同时,我已经创建了 CCACHE-66 的问题。

你有没有可以让我查看的产生相同问题的示例?

Paweł Wilk 评论了 Mar 3, 2023 by Paweł Wilk
谢谢!

以下是一些示例:


(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
Paweł Wilk 回答了 Apr 19 by Paweł Wilk

为 CCACHE-66 附加补丁。

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

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

...