トランジェントを使用したパフォーマンス指向のソリューションreduce-kv
と、より小さいマップを反復するためのサイズ チェック:
(defn merge-common-with [f m1 m2]
(let [[a b] (if (< (count m1) (count m2))
[m1 m2]
[m2 m1])]
(persistent!
(reduce-kv (fn [out k v]
(if (contains? b k)
(assoc! out k (f (get a k) (get b k)))
out))
(transient {})
a))))
REPL で、質問テキストのサンプル データを使用します。
(merge-common-with + (data "Bob") (data "Jane"))
;= {"A" 5.5, "B" 6.0}
上記が多くの状況で最速のアプローチであると予想していますが、実際のユースケースに典型的なデータを使用してベンチマークすることは間違いありません. これは、質問テキストから使用したCriteriumベースのベンチマークです ( wins here )。data
merge-common-with
(require '[criterium.core :as c])
(def a (data "Bob"))
(def b (data "Jane"))
;; Hendekagon's elegant approach amended to select-keys on both sides
(defn merge-common-with* [f a b]
(merge-with f
(select-keys a (keys b))
(select-keys b (keys a))))
;; benchmarks for three approaches follow, fastest to slowest
(c/bench (merge-common-with + a b))
Evaluation count : 74876640 in 60 samples of 1247944 calls.
Execution time mean : 783.233604 ns
Execution time std-deviation : 7.660391 ns
Execution time lower quantile : 771.514052 ns ( 2.5%)
Execution time upper quantile : 802.622953 ns (97.5%)
Overhead used : 1.266543 ns
Found 3 outliers in 60 samples (5.0000 %)
low-severe 3 (5.0000 %)
Variance from outliers : 1.6389 % Variance is slightly inflated by outliers
(c/bench (merge-matching + a b)) ; amalloy's approach
Evaluation count : 57320640 in 60 samples of 955344 calls.
Execution time mean : 1.047921 µs
Execution time std-deviation : 16.221173 ns
Execution time lower quantile : 1.025001 µs ( 2.5%)
Execution time upper quantile : 1.076081 µs (97.5%)
Overhead used : 1.266543 ns
(c/bench (merge-common-with* + a b))
WARNING: Final GC required 3.4556868188006065 % of runtime
Evaluation count : 33121200 in 60 samples of 552020 calls.
Execution time mean : 1.862483 µs
Execution time std-deviation : 26.008801 ns
Execution time lower quantile : 1.821841 µs ( 2.5%)
Execution time upper quantile : 1.914336 µs (97.5%)
Overhead used : 1.266543 ns
Found 1 outliers in 60 samples (1.6667 %)
low-severe 1 (1.6667 %)
Variance from outliers : 1.6389 % Variance is slightly inflated by outliers