我在使用core.cache
与LazyMap
的组合。懒映射是类似于map的对象(一种封装map并添加一些逻辑的新数据类型,以自动强制延迟键相关值的新数据类型)。
当我开始将懒映射作为FIFO缓存的值时,我发现所有值都仅在映射进入缓存后立即实现。经过一番探究,我发现这是由clojure.core.cache.wrapped/lookup-or-miss
中的表达式(= ::expired v)
导致的。
发生的事情是,=
内部调用clojure.lang.Util/equiv
(因为LazyMap
实现了IPersistentCollection
),然后,经过一些分派,调用equiv
来检查懒映射的内容是否等于其他对象(隐含其他映射)。这是期望的行为,懒映射实现所有值以实现比较。
然而,当我们比较类似映射的对象与不是映射(也不是集合)的某些东西时,如果我们知道它肯定返回false
,则短路将受欢迎。但这可能更多与Clojure本身和类似CLJ-1375的东西有关。
如果这不会太成问题,则可以在core.cache
这一边这样做:
(= ::expired v)
替换为(identical? ::expired v)
在clojure.core.cache.wrapped
中。
这不仅将修复像我这样的角落案例,还可以稍微加快一些速度(当涉及到Clojure关键字时,显式的引用相等非常有用)。
还可以更改的表达式
(= ::nope ret)
和来自clojure.core.cache
的(= ::nil v)
。