Skip to content

Instantly share code, notes, and snippets.

@richhickey
Created December 12, 2012 15:47
Show Gist options
  • Save richhickey/4268852 to your computer and use it in GitHub Desktop.
Save richhickey/4268852 to your computer and use it in GitHub Desktop.
twiddling with map perf
(ns bitmapmap-test.core-test
(:use clojure.test))
#_(defn bitmap-map
"Constructs a bitmap-map. If any keys are equal, they are handled as
if by repeated uses of assoc."
{:added "1.6"
:static true}
([] (. clojure.lang.PersistentBitmapMap EMPTY))
([& keyvals]
(clojure.lang.PersistentBitmapMap/create (to-array keyvals))))
(defmacro time-taken
"Evaluates expr and prints and returns the time it took, in msec."
[expr]
`(let [start# (System/nanoTime)
_# ~expr
time-ms# (/ (double (- (System/nanoTime) start#)) 1000000.0)]
(prn (str "Elapsed time: " time-ms# " msecs"))
time-ms#))
(defn test-get [k]
(fn [name m ntimes]
(if (instance? clojure.lang.PersistentArrayMap m)
#(do
(print \tab name \tab)
(time-taken (dotimes [_ ntimes]
(get m k))))
#(do
(print \tab name \tab)
(time-taken (dotimes [_ ntimes]
(get m k)))))))
(defn test-get2 [k]
(fn [name m ntimes]
(if (instance? clojure.lang.PersistentArrayMap m)
#(do
(print \tab name \tab)
(time-taken (dotimes [_ ntimes]
(get m k))))
#(do
(print \tab name \tab)
(time-taken (dotimes [_ ntimes]
(get m k)))))))
(defn test-get3 [k]
(fn [name m ntimes]
(if (instance? clojure.lang.PersistentArrayMap m)
#(do
(print \tab name \tab)
(time-taken (dotimes [_ ntimes]
(get m k))))
#(do
(print \tab name \tab)
(time-taken (dotimes [_ ntimes]
(get m k)))))))
(defn test-assoc [k]
(fn [name m ntimes]
(if (instance? clojure.lang.PersistentArrayMap m)
#(do
(print \tab name \tab)
(time-taken (dotimes [_ ntimes]
(assoc m k "42"))))
#(do
(print \tab name \tab)
(time-taken (dotimes [_ ntimes]
(assoc m k "42")))))))
(defn test-assoc2 [k]
(fn [name m ntimes]
(if (instance? clojure.lang.PersistentArrayMap m)
#(do
(print \tab name \tab)
(time-taken (dotimes [_ ntimes]
(assoc m k "42"))))
#(do
(print \tab name \tab)
(time-taken (dotimes [_ ntimes]
(assoc m k "42")))))))
(defn test-assoc3 [k]
(fn [name m ntimes]
(if (instance? clojure.lang.PersistentArrayMap m)
#(do
(print \tab name \tab)
(time-taken (dotimes [_ ntimes]
(assoc m k "42"))))
#(do
(print \tab name \tab)
(time-taken (dotimes [_ ntimes]
(assoc m k "42")))))))
(defn runa [testfn am N]
(let [f (testfn "array-map" am N)]
(dotimes [_ 10] (f))))
(defn runh [testfn hm N]
(let [f (testfn "hash-map" hm N)]
(dotimes [_ 10] (f))))
(defn test-maps [name args testfn]
(let [am (apply array-map args)
;;bm (apply bitmap-map args)
hm (apply hash-map args)
N 2e6]
(println "Testing maps of size" (.size am) "with" name)
(dotimes [n 3]
(println (str " Run #" (inc n)))
;;(let [f (testfn "bitmap-map" bm N)] (dotimes [_ 10] (f)))
(runa testfn am N)
(runh testfn hm N))
(let [am-time ((testfn "array-map" am N))
;;bm-time ((testfn "bitmap-map" bm N))
hm-time ((testfn "hashmap" hm N))
]
(println "array-map/hashmap" (/ am-time hm-time))
;;(println "bitmap-map/hashmap" (/ bm-time hm-time))
;;(println "bitmap/arraymap" (/ bm-time am-time))
)))
(defn mapargs [size]
(mapcat (juxt (comp vector str) identity)
(range size)))
(defn kwargs [size]
(mapcat (juxt (comp keyword str) identity)
(range size)))
(defn strargs [size]
(mapcat (juxt str identity)
(range size)))
(defn idargs [size]
(mapcat (juxt identity identity)
(range size)))
(deftest get-test
;;(test-maps "get with nonidentical coll key" (mapargs 3) (test-get (vector "2")))
;;(test-maps "get with nonidentical coll key" (mapargs 4) (test-get (vector "3")))
;;(test-maps "get with nonidentical coll key" (mapargs 5) (test-get (vector "4")))
#_(doseq [size [3 5]]
(let [args (mapargs size)
key (last (butlast args))]
(test-maps "get with identical key" args (test-get key))))
(doseq [size [3 5]]
(let [args (kwargs size)
key (last (butlast args))]
(test-maps "get with keyword key" args (test-get key))))
(doseq [size [3 5]]
(let [args (strargs size)
key (last (butlast args))]
(test-maps "get with string key" args (test-get2 key))))
(doseq [size [3 5]]
(let [args (idargs size)
key (last (butlast args))]
(test-maps "get with num key" args (test-get3 key)))))
(deftest assoc-existing-key-test
;;(test-maps "assoc with nonidentical key" (mapargs 3) (test-assoc (vector "2")))
;;(test-maps "assoc with nonidentical key" (mapargs 4) (test-assoc (vector "3")))
;;(test-maps "assoc with nonidentical key" (mapargs 5) (test-assoc (vector "4")))
#_(doseq [size [3 5]]
(let [args (mapargs size)
key (last (butlast args))]
(test-maps "assoc with identical key" args (test-assoc key))))
(doseq [size [3 5]]
(let [args (kwargs size)
key (last (butlast args))]
(test-maps "assoc with keyword key" args (test-assoc key))))
(doseq [size [3 5]]
(let [args (strargs size)
key (last (butlast args))]
(test-maps "assoc with string key" args (test-assoc2 key))))
(doseq [size [3 5]]
(let [args (idargs size)
key (last (butlast args))]
(test-maps "assoc with num key" args (test-assoc3 key)))))
#_(deftest assoc-new-key-test
(test-maps "assoc with new key" (mapargs 3) (test-assoc (vector "foo")))
(test-maps "assoc with new key" (mapargs 4) (test-assoc (vector "foo")))
(test-maps "assoc with new key" (mapargs 5) (test-assoc (vector "foo"))))
(deftest assoc-new-keyword-test
(test-maps "assoc with new keyword" (kwargs 3) (test-assoc (keyword "foo")))
;;(test-maps "assoc with new keyword" (kwargs 4) (test-assoc (keyword "foo")))
(test-maps "assoc with new keyword" (kwargs 5) (test-assoc (keyword "foo"))))
(comment
(clojure.test/run-tests 'bitmapmap-test.core-test)
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment