I've been doing some performance tests on various floating point
operations. In particular, I wanted to check what would be the fastest way
to implement a 2-d floating point vector in clojure.
Here's my tests:
;;; V+ Tests
;;; Implementing floating-point vectors as:
;;; structs, deftype, vector
(defrecord v2r
[^Double x ^Double y])
(defn rv+
[^v2r v1 ^v2r v2]
(v2r. (+ (.x v1) (.x v2))
(+ (.y v1) (.y v2))))
(deftype v2t
[^Double x ^Double y])
(defn tv+
[^v2t v1 ^v2t v2]
(v2t. (+ (.x v1) (.x v2))
(+ (.y v1) (.y v2))))
(defn vv+
[v1 v2]
(mapv + v1 v2))
(defn testvecs
"Tests the vector add operations by reducing a
random list by each of the v+ operations on
identical sets of random vectors"
[n]
(let [nums (repeatedly (* 2 n) rand)
vpairs (partition 2 nums)
v2r-list (apply list (map (fn [[x y]] (v2r. x y)) vpairs))
v2t-list (apply list (map (fn [[x y]] (v2t. x y)) vpairs))
v2v-list (apply list (map vec vpairs))]
(println "V2 Record:")
(bench (reduce rv+ v2r-list))
(println "V2 Type:")
(bench (reduce tv+ v2t-list))
(println "V2 Vector:")
(bench (reduce vv+ v2v-list))
(println "Just Doubles:")
(bench (reduce + nums))))
Here's my output:
*V2 Record:*
Evaluation count : 420 in 60 samples of 7 calls.
Execution time mean : 164.379725 ms
Execution time std-deviation : 4.478128 ms
Execution time lower quantile : 149.546749 ms ( 2.5%)
Execution time upper quantile : 172.317132 ms (97.5%)
Overhead used : 1.873322 ns
Found 8 outliers in 60 samples (13.3333 %)
low-severe 4 (6.6667 %)
low-mild 3 (5.0000 %)
high-mild 1 (1.6667 %)
Variance from outliers : 14.2105 % Variance is moderately inflated by
outliers
*V2 Type:*
Evaluation count : 1860 in 60 samples of 31 calls.
Execution time mean : 32.238857 ms
Execution time std-deviation : 2.331682 ms
Execution time lower quantile : 26.769206 ms ( 2.5%)
Execution time upper quantile : 35.318368 ms (97.5%)
Overhead used : 1.873322 ns
Found 8 outliers in 60 samples (13.3333 %)
low-severe 5 (8.3333 %)
low-mild 3 (5.0000 %)
Variance from outliers : 53.4940 % Variance is severely inflated by
outliers
*V2 Vector:*
Evaluation count : 2040 in 60 samples of 34 calls.
Execution time mean : 30.175015 ms
Execution time std-deviation : 3.870306 ms
Execution time lower quantile : 21.877116 ms ( 2.5%)
Execution time upper quantile : 37.668717 ms (97.5%)
Overhead used : 1.873322 ns
Found 10 outliers in 60 samples (16.6667 %)
low-severe 5 (8.3333 %)
low-mild 2 (3.3333 %)
high-mild 3 (5.0000 %)
Variance from outliers : 78.9869 % Variance is severely inflated by
outliers
*Just Doubles:*
Evaluation count : 20640 in 60 samples of 344 calls.
Execution time mean : 4.309871 ms
Execution time std-deviation : 537.444033 µs
Execution time lower quantile : 2.389294 ms ( 2.5%)
Execution time upper quantile : 4.716009 ms (97.5%)
Overhead used : 1.873322 ns
Found 8 outliers in 60 samples (13.3333 %)
low-severe 5 (8.3333 %)
low-mild 2 (3.3333 %)
high-mild 1 (1.6667 %)
Variance from outliers : 78.9282 % Variance is severely inflated by
outliers
The performance is amazingly better when using primitive doubles, even
though all operations are doing effectively the same thing: 20000 floating
point add operations. I assume that the overhead of allocating a new
vector2 object is responsible for the decline in performance.
Did I use type hints correctly? Is there a way to keep the "x and y"
vector abstraction and still get something approaching primitive
performance?
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.