Reputation: 83
i want to ask about core.matrix dot product performance, is there a technique to optimize dot-product function ?
Because i found that in Java, C, or even in HipHipArray library, the dot product performance is extremely faster than core matrix dot product. I conduct a little benchmark by looping the dot product function until 800000 steps, and i found in Java = 12 ms, C = 22 ms, and core.matrix = 1300 ms ( if using core.matrix.dot ), if using hiphip array in clojure, i found its resulting 300 ms for 800000 iteration dot-product.
Actually i want to use hiphip array and core matrix when executing the core.matrix.dot-product, but the function dot-product demanding double-array format for the input, which is also bottleneck process for core.matrix because the row of matrix should be cast into double-array form before running dot-product.
Any solution ?
Upvotes: 0
Views: 562
Reputation: 84331
core.marix performance is heavily dependent on which matrix implementation you use. The default is a pure Clojure implementation based on persistent vectors. Two other implementations are listed in the README (vectorz-clj and Clatrix) and a complete list is available at runtime (clojure.core.matrix.implementations/KNOWN_IMPLEMENTATIONS
; this is where set-current-implementation
looks up the keyword passed to it, see below).
To demonstrate just how dramatic a performance difference switching to a different implementation can make, consider this collection of Criterium benchmarks:
;; default implementation
(let [v (mat/matrix (mapv double (range 10000)))]
(c/quick-bench (mat/dot v v)))
WARNING: Final GC required 49.98723291004293 % of runtime
Evaluation count : 282 in 6 samples of 47 calls.
Execution time mean : 2.219186 ms
Execution time std-deviation : 72.665087 µs
Execution time lower quantile : 2.155165 ms ( 2.5%)
Execution time upper quantile : 2.336716 ms (97.5%)
Overhead used : 15.800986 ns
Found 1 outliers in 6 samples (16.6667 %)
low-severe 1 (16.6667 %)
Variance from outliers : 13.8889 % Variance is moderately inflated by outliers
(mat/set-current-implementation :vectorz)
(let [v (mat/matrix (mapv double (range 10000)))]
(c/quick-bench (mat/dot v v)))
WARNING: Final GC required 55.499903895118344 % of runtime
Evaluation count : 61518 in 6 samples of 10253 calls.
Execution time mean : 9.964186 µs
Execution time std-deviation : 171.566491 ns
Execution time lower quantile : 9.751079 µs ( 2.5%)
Execution time upper quantile : 10.161758 µs (97.5%)
Overhead used : 15.800986 ns
(mat/set-current-implementation :clatrix)
(let [v (mat/matrix (mapv double (range 10000)))]
(c/quick-bench (mat/dot v v)))
WARNING: Final GC required 56.489827272630386 % of runtime
Evaluation count : 61992 in 6 samples of 10332 calls.
Execution time mean : 9.898032 µs
Execution time std-deviation : 266.379479 ns
Execution time lower quantile : 9.594174 µs ( 2.5%)
Execution time upper quantile : 10.236125 µs (97.5%)
Overhead used : 15.800986 ns
That's > 2 ms with the default implementation and just under 10 µs with vectorz-clj or Clatrix; in other words, vectorz-clj is ~222x faster than the default impl on this benchmark.
Upvotes: 1