2024年Clojure调查问卷中分享您的想法!

欢迎!请参阅关于页面,了解更多关于本站如何运作的信息。

0
Java互操作

reduce函数适用于Java maps,但reduce-kv不适用

`
user=> (def clojure-map {1 2 3 4})

'user/clojure-map

user=> (def java-map (java.util.HashMap. {1 2 3 4}))

'user/java-map

user=> (reduce (fn [sum [k v]] (+ sum k v)) 0 java-map)
10
user=> (reduce-kv + 0 clojure-map)
10
user=> (reduce-kv + 0 java-map)

IllegalArgumentException No implementation of method: :kv-reduce of protocol: #'clojure.core.protocols/IKVReduce found for class: java.util.HashMap clojure.core/-cache-protocol-fn\
(core_deftype.clj:544)
`

在常规reduce中解构参数非常简单,但这有一些性能影响。以下示例,在将该补丁中实现的reduce-kv对java.util.Map的实现运行时,提供了7倍的加速

`
user=> (def big-clojure-map (into {} (map #(vector % %) (range 10000))))

'user/big-clojure-map

user=> (def big-java-map (java.util.HashMap. big-clojure-map))
反射警告,/tmp/form-init7130245387362554027.clj:1:19 - 无法解析对java.util.HashMap构造函数的调用。

'user/big-java-map

user=> (defn reduce-sum [m] (reduce (fn [sum [k v]] (+ sum k v)) 0 m))

'user/reduce-sum

user=> (defn reduce-sum-kv [m] (reduce-kv (fn [sum k v] (+ sum k v)) 0 m))

'user/reduce-sum-kv

user=> (time (dotimes [_ 1000] (reduce-sum big-java-map)))
"Elapsed time: 2624.692113 msecs"
nil
user=> (time (dotimes [_ 1000] (reduce-sum-kv big-java-map)))
"Elapsed time: 376.802454 msecs"
nil
`

1 个答案

0
参考: https://clojure.atlassian.net/browse/CLJ-1762 (由alex+import报告)
...