clojure-dev

Issues: https://clojure.atlassian.net/browse/CLJ | Guide: https://insideclojure.org/2015/05/01/contributing-clojure/
borkdude 2019-02-26T09:25:24.063200Z

OK, with these changes: https://github.com/clojure/clojure/compare/master...borkdude:map-optimizations And this benchmark:

clj -Sdeps '{:deps {org.clojure/clojure {:mvn/version "1.11.0-master-SNAPSHOT"} criterium/criterium {:mvn/version "RELEASE"}}}'
user=> (use 'criterium.core)
nil
user=> (defn merge-benchmark [size] (let [m1 (zipmap (range size) (range size)) m2 (zipmap (range size (* 2 size)) (range size (* 2 size)))] (println (type m1) (type m2)) (quick-bench (merge m1 m2))))
#'user/merge-benchmark
It’s starting to pay off with maps > 64 kv-pairs or so. Below that the performance is roughly the same between 16-64 elements and maybe a tad slower below 16 elements.

borkdude 2019-02-26T09:27:30.063500Z

Here’s a gist with the exact numbers: https://gist.github.com/borkdude/b6e52bc1bd32512aa43015724cda46da

borkdude 2019-02-26T09:35:33.064Z

so for a 2000 element map it would mean a speedup of 35%

mpenet 2019-02-26T09:37:36.064400Z

small maps are super common tho, ex ring

borkdude 2019-02-26T09:38:25.065300Z

yeah. maybe a count on the seq before doing the optimization would make sense?

borkdude 2019-02-26T09:40:05.065700Z

or we could just decide that this is not worth optimizing. chances are that Rich has already thought about this case

borkdude 2019-02-26T09:40:40.066300Z

for PersistentArrayMap the override could be removed since those are small maps all the time

borkdude 2019-02-26T10:03:15.067400Z

The solution with counting up front makes it slower in all cases. So the trade off is to optimize for big maps (> 64) or smaller maps (< 64). I guess it’s very common to have small maps in Clojure, hence the optimization is probably off the table.

borkdude 2019-02-26T10:05:54.068300Z

People using big maps can write their own transient merge probably