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 clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
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 clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to