Hi! I'm trying to type-hint dotprod-3 to avoid reflection warnings. I'm not sure where to start. Any pointers?
The warning is indeed opaque.
It surfaces because aget wants an array but doesn't know what xs and ys are.
Assuming those are arrays of double primitives, you can type-hint them with ^doubles in the dotprod-3 args vector.
I had to do ^floats since I used float-array for some reason (and not double-array ).
WIth those tweaks, my measured execution time drops from 3.1 seconds to 0.8 ms:
(set! *warn-on-reflection* true)
(defn dotprod-3 [^floats xs ^floats ys]
(let [len (min (count xs) (count ys))]
(loop [i 0
accum 0.0]
(if (< i len)
(recur (inc i)
(+ accum (* (aget xs i) ; <- first warning
(aget ys i) ; <- second warning
)))
accum))))
(let [xs (float-array (range 1000000))
ys (float-array (map - (range 1000000)))]
(measure-ms (dotprod-3 xs ys)))
;; => [-3.3333283333312755E17 0.852375]
Thanks a lot, @p-himik!
It appears I tried to type-hint all the wrong expressions.Just in case - if it's something performance-critical, you will likely benefit from some specialized library, like e.g. tablecloth.
Absolutely. My goal now is to demonstrate why tablecloth-like techniques give speedups. I aim to argue that avoiding allocation is good, and to keep densely packed arrays of numbers speed up iterating through those numbers. For that purpose, I want nunbers on the "bad solutions"!
If you need to do fast math for prod. workloads, then have a look at some specialized library, like, well, fastmath (or alternatives). https://github.com/generateme/fastmath?tab=readme-ov-file#alternatives
Articles by Dragan Djuric, Olexander Yakushev, and Chris Neurenberger would be other go-to resources on making your Clojure go faster.
@adityaathalye absolutely! As I mentioned in my last comment, the java array code aims to demonstrate how typed Java arrays can be faster than Clojure vectors, before I show a solution wth https://github.com/scicloj/tablecloth. The java array solution isn't going into production 🙂
Another potentially useful data point - writing the same code in plain Java.