Skip to content

Instantly share code, notes, and snippets.

(ns test.arrays
(:gen-class))
(comment"
Simple speed comparison:
- Java arrays
- Immutable deftype
- Mutable deftype.
Result on my laptop with
* N=500,000,000
* Clojure 1.2 equiv branch
* Running from command line
Mutable Java arrays (time-arr): 17.8s
Immutable deftype (time-type) : 10.5s
Mutable deftype (time-mtype) : 2.1s
Plain Java (not shown) : 2.1s
")
; Vector with 3 values
(definterface IVec3
(^double x [])
(^double y [])
(^double z [])
(add [^double x ^double y ^double z]))
; Mutable impl.
(deftype Vec3M [^{:unsynchronized-mutable true :tag double} x
^{:unsynchronized-mutable true :tag double} y
^{:unsynchronized-mutable true :tag double} z]
IVec3
(x [_] x)
(y [_] y)
(z [_] z)
(add [self x2 y2 z2]
(set! x (+ x x2))
(set! y (+ y y2))
(set! z (+ z z2))
self)
Object
(toString [_] (str "[" x " " y " " z "]")))
; Immutable impl.
(deftype Vec3 [^double x ^double y ^double z]
IVec3
(x [_] x)
(y [_] y)
(z [_] z)
(add [self x2 y2 z2]
(Vec3. (+ x x2) (+ y y2) (+ z z2)))
Object
(toString [_] (str "[" x " " y " " z "]")))
; Java array
(defn ^:static test-arr [^long n]
(let [v (double-array 3) ]
(dotimes [_ n]
(aset v 0 (+ (aget v 0) 0.1))
(aset v 1 (+ (aget v 1) 0.2))
(aset v 2 (+ (aget v 2) 0.3)))
[(aget v 0) (aget v 1) (aget v 2)]))
; Mutable deftype
(defn ^:static test-mtype [^long n]
(let [v (Vec3M. 0.0 0.0 0.0) ]
(dotimes [_ n]
(.add v 0.1 0.2 0.3))
[(.x v) (.y v) (.z v)]))
; Immutable deftype
(defn ^:static test-type [^long n]
(loop [v (Vec3. 0.0 0.0 0.0)
i 0]
(if (>= i n)
[(.x v) (.y v) (.z v) ]
(recur (.add v 0.1 0.2 0.3) (inc i)))))
(defn -main [& args]
(let [[n t x] args
n (Integer/parseInt n) ]
(when (= x "-wait") ; wait for the profiler
(println "Press enter to start")
(read-line))
(let [res (condp = t
"array" (test-arr n)
"type" (test-type n)
"mtype" (test-mtype n)) ]
(println (map #(format "%.2f" %) res))
(println "Bye from Clojure"))))
(def *n* "50000000")
(defn time-arr []
(time (-main *n* "array")))
(defn time-type []
(time (-main *n* "type")))
(defn time-mtype []
(time (-main *n* "mtype")))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment