Created
August 18, 2017 02:35
-
-
Save jgpc42/97fdcf12d4a2977e15b23001f0a612db to your computer and use it in GitHub Desktop.
Clojure integer array hashcode benchmark
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; $ java -cp ~/.lein/self-installs/leiningen-2.7.1-standalone.jar clojure.main hashcode-bench.clj | |
(println "Java" (System/getProperty "java.version")) | |
(println "Clojure" (apply str ((juxt :major (constantly \.) :minor) *clojure-version*))) | |
;; => Java 1.8.0_131 | |
;; => Clojure 1.8 | |
(require '[cemerick.pomegranate :as pom]) | |
(pom/add-dependencies | |
:coordinates '[[criterium "0.4.4"] | |
[insn "0.1.0"]] | |
:repositories {"clojars" "https://clojars.org/repo"}) | |
(require '[criterium.core :as crit] | |
'[insn.clojure :as bc]) | |
(import [java.util Arrays]) | |
(set! *warn-on-reflection* true) | |
(set! *unchecked-math* :warn-on-boxed) | |
(bc/defn bytecode ^long [arr] | |
[[:aload 1] [:ifnull :L/NULL] ;; if arr == null then goto NULL | |
[:aload 1] [:checkcast [:int]] [:astore 1] ;; arr = (int[]) arr | |
[:aload 1] [:arraylength] [:istore 2] ;; len = arr.length | |
[:ldc 0] [:istore 3] ;; i = 0 | |
[:ldc 1] [:istore 4] ;; h = 1 | |
[:mark :L/LOOP] | |
[:iload 2] [:iload 3] [:if-icmpeq :L/RET] ;; if len == i then goto RET | |
[:ldc 31] [:iload 4] [:imul] ;; push h * 31 | |
[:aload 1] [:iload 3] [:iaload] ;; push arr[i] | |
[:iadd] [:istore 4] ;; add pushed values, store into h | |
[:iinc 3 1] [:goto :L/LOOP] ;; i++, goto LOOP | |
[:mark :L/RET] | |
[:iload 4] [:i2l] [:lreturn] ;; return h as long | |
[:mark :L/NULL] | |
[:ldc2 0] [:lreturn]]) ;; return 0L | |
(defn clojure ^long [^ints arr] | |
(if (nil? arr) | |
0 | |
(let [len (long (alength arr))] | |
(loop [i 0, h 1] | |
(if (< i len) | |
(recur (unchecked-inc i) | |
(unchecked-add-int | |
(unchecked-multiply-int | |
(unchecked-int h) (unchecked-int 31)) | |
(aget arr (unchecked-int i)))) | |
h))))) | |
(defn java ^long [^ints arr] | |
(Arrays/hashCode arr)) | |
(let [array (int-array (range 100)) | |
exp (java array)] | |
(crit/bench (assert (== exp (bytecode array)))) ;; => Execution time mean : 89.884445 ns | |
(crit/bench (assert (== exp (clojure array)))) ;; => Execution time mean : 125.551577 ns | |
(crit/bench (assert (== exp (java array))))) ;; => Execution time mean : 89.781852 ns |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment