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

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

0
集合
已关闭

https://github.com/clojure/clojure/blob/010864f/src/clj/clojure/core.clj#L6553-L6562

因为 PHM 实现了 clojure.lang.IKVReduce 并且 IPersistentMap,所以它们会通过支持 reduce-kv 的协议(persistent.core.protocols/IKVReduce)进行非确定性派发。

解决此问题的一个潜在方法是在 reduce-kv 内部添加对 clojure.lang.IKVReduce 的实例检查(这类似于 reduce 检查 IReduceInit)。

另一种方法是扩展协议以直接针对 PersistentHashMap 和 PersistentArrayMap(同时保留现有的扩展)。

已关闭,备注: 在 1.11.0-alpha2 中修复

3 个答案

0

评论者:bronsa

CLJ-1807 为这类问题提供了一般性解决方案

0
_评论者:gshayban_

复现代码


(def C (atom 0))

;; 重新扩展以进行排错
(extend-protocol clojure.core.protocols/IKVReduce
 ;;slow path default
 clojure.lang.IPersistentMap
 (kv-reduce
   [amap f init]
   (swap! C inc)
   (reduce (fn [ret [k v]] (f ret k v)) init amap)))

(reduce-kv (fn [_ _ _]) nil (array-map 1 2 3 4))
(println "slowpaths" @C)
(reduce-kv (fn [_ _ _]) nil (hash-map 1 2 3 4))
(println "slowpaths" @C)




重现输出

➜  dev /usr/lib/jvm/java-8-openjdk/bin/java -cp $(clojure -Spath) clojure.main kvfastpath.clj
slowpaths 1
slowpaths 2
➜  dev /usr/lib/jvm/java-11-openjdk/bin/java -cp $(clojure -Spath) clojure.main kvfastpath.clj
slowpaths 0
slowpaths 0
0
by
参考: https://clojure.atlassian.net/browse/CLJ-1879(由 gshayban 报告)
...