Welcome! Please see the About page for a little more info on how this works.

+3 votes
in Collections by

merge is implemented as

(defn merge
 ;; stuff removed
  [& maps]
  (when (some identity maps)
    (reduce1 #(conj (or %1 {}) %2) maps)))

This is somewhat suboptimal from a couple of reasons. reduce1 is slower than reduce (might not matter when the number of maps is small, but perhaps more importantly, in the case where you just want to merge two maps, it does a lot of unnecessary work, since merging two maps is basically

(when (or m1 m2) (conj (or m1 {}) m2))

Would it be reasonable to have a multi arity version of merge which optimized for this case?
A quick benchmark shows a potential for a 4 times speed up in this case.

I've looked through Jira, but surprisingly, I wasn't able to find a ticket for this?

2 Answers

+1 vote

I think there are multiple, but https://clojure.atlassian.net/browse/CLJ-1458

+1 vote

Yeah, merge has been subpar for years.

https://github.com/bsless/clj-fast has some alternatives with benchmarks.

Lots of different takes there along with implementations with some interesting notes in https://github.com/bsless/clj-fast/issues/1 .

Welcome to Clojure Q&A, where you can ask questions and receive answers from members of the Clojure community.