Table of Contents
lein with-profile +direct,+bench,+cli,+test-build do clean, uberjar
java -Xmx8G -Xms8G \
-XX:+UseG1GC \
-jar target/uberjar/clj-fast-0.0.9-SNAPSHOT.jar \
--max-width 4 \
--max-depth 4 \
--quick false \
--types "keyword?" \
--name new \
assoc assoc-in assoc-rec get get-in get-rec memoize merge select-keys update-in
Load analysis.clj
and:
(ns clj-fast.analysis)
(def raw-data
(-> "./benchmarks/all-clj-fast-bench.edn"
load-results
(update :get-rec #(map (fn [m] (assoc m :width 0)) %))
(update :merge #(remove (comp #{1} :keys) %))))
(def all-charts
(conj
(common-charts raw-data)
(chart-get :get raw-data)
(chart-get :get-rec raw-data)
(chart-assoc-rec raw-data)))
(logify :merge all-charts)
(write-charts all-charts)
Criterium is used to run quick benchmarks.
Benchmarks were run with 8GB heap and G1 garbage collection.
get
was tested on map
, record
and fast-map
, fast-get
was tested on fast-map
.
Moreover, different get methods were tested:
.get
from record..field
from record.get
from record ~50% slower than from map.fast-get
from fast-map
~ 2x faster than get
ting from regular
map, with gains increasing as the map becomes larger. (Metosin)valAt
all have
approximately the same performance, however, there are more levels of
indirection when calling a keyword, less than when invoking a map, and
zero when calling valAt
.get
are fasterget from map | get from record |
---|---|
Assoc and fast assoc performance are tested with maps and records.
assoc
to record is as fast as assoc
ing to map.fast-assoc
~ 5.7% faster than assoc
. (Metosin)fast map merge was implemented by Metosin and uses kv-reduce
to assoc
one map into another.
Compare to regular merge for the keys=2 case.
Several inline implementations were compared:
inline-merge
: uses conj
directly on all input maps instead of reducing.inline-fast-map-merge
: inline merges maps using Metosin's fast-map-merge
.inline-tmerge
: Uses transients to merge the maps. Basic implementation by Joinr.fast-map-merge is faster than regular merge, especially for smaller maps, with diminishing returns as maps get bigger.
Sees diminishing returns on the benefit of merging more maps, but some speedup is measurable. tmerge is slower for small maps but for larger maps is faster than regular merge. The speedup by fast-map-merge is about 15-25%, width diminishing returns the bigger maps get.
Execution time is presented in logarithmic scale due to the huge differences for different map sizes.
get-in
was tested against an inlined implementation.
Inline implementation faster by a factor of 4-5.
Closely related to get-in
memoize was tested against an inlining implementation using a clojure atom
(memoize-n
) and one using a concurrent-hash-map (memoize-c
)
Different implementation are faster depending on the type of the memoized arguments:
memoize
: core.memoize, always slowermemoize-n
is better when all arguments are keywords.memoize-c
is better for any other case.hm-memoize
is faster than memoize
but slower than memoize-c
.cm-memoize
is faster than memoize
but slower than memoize-c
.Assoc-in is tested vs. an inlined implementation with vanilla maps, gets and assoc, all core functions.
select-keys
was tested against two inlined implementations:
Inline implementation faster by a factor of 10 or more, depends on the number of selected keys.
Can you improve this documentation?Edit on GitHub
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close