Yup. Reflection is issue, I needed type hint.
However, on another note, I notice that in your first test case, your
evaluation takes about 3 ms, but on my machine it takes 76 ms. I'm running
a Xeon CPU at 3.5 GHZ, clojure-1.7-RC1. What could cause such a huge
different timing?
Thanks.
On Wednesday, June 10, 2015 at 8:04:00 PM UTC-5, Steven Yi wrote:
>
> As mentioned by Colin and Andy, I would guess it would be some form of
> boxing and reflection going on. I tried the following:
>
> (defn array-max [^doubles arr]
>
> (let [len (alength arr)]
>
> (loop [m Double/NEGATIVE_INFINITY indx 0]
>
> (if (< indx len)
>
> (recur (max m (aget arr indx)) (unchecked-inc indx))
>
> m))))
>
>
> user=> (let [vs (amap (double-array 1280000) idx ret (Math/random))]
>
> (time (array-max vs)))
>
> "Elapsed time: 3.719835 msecs"
>
> To note, if you check out the source of areduce:
>
> user=> (source areduce)
>
> (defmacro areduce
>
> "Reduces an expression across an array a, using an index named idx,
>
> and return value named ret, initialized to init, setting ret to the
>
> evaluation of expr at each step, returning ret."
>
> {:added "1.0"}
>
> [a idx ret init expr]
>
> `(let [a# ~a]
>
> (loop [~idx 0 ~ret ~init]
>
> (if (< ~idx (alength a#))
>
> (recur (unchecked-inc ~idx) ~expr)
>
> ~ret))))
>
>
> It's just a macro, and so typehinting is going to play a factor. For
> example, with areduce and a type hint on the array:
>
>
> (defn array-max2 [^doubles arr]
>
> (areduce arr idx ret Double/NEGATIVE_INFINITY (max ret (aget arr idx))))
>
> user=> (let [vs (amap (double-array 1280000) idx ret (Math/random))] (time
> (array-max vs)))
>
> "Elapsed time: 3.314599 msecs"
>
>
> But with no type hint on arr:
>
>
> (defn array-max2 [arr]
>
> (areduce arr idx ret Double/NEGATIVE_INFINITY (max ret (aget arr idx))))
>
> user=> (let [vs (amap (double-array 1280000) idx ret (Math/random))] (time
> (array-max2 vs)))
>
> "Elapsed time: 35612.919192 msecs"
>
>
> Without a typehint on the arr argument, I also do get boxed math and
> reflection warnings:
>
>
> Reflection warning,
> /private/var/folders/0k/xj_drd990xxf4q99n2bdknrc0000gn/T/form-init1595291808747030463.clj:2:3
>
> - call to static method alength on clojure.lang.RT can't be resolved
> (argument types: unknown).
>
> Boxed math warning,
> /private/var/folders/0k/xj_drd990xxf4q99n2bdknrc0000gn/T/form-init1595291808747030463.clj:2:3
>
> - call: public static boolean clojure.lang.Numbers.lt
> (long,java.lang.Object).
>
> Reflection warning,
> /private/var/folders/0k/xj_drd990xxf4q99n2bdknrc0000gn/T/form-init1595291808747030463.clj:2:58
>
> - call to static method aget on clojure.lang.RT can't be resolved (argument
> types: unknown, int).
>
> Boxed math warning,
> /private/var/folders/0k/xj_drd990xxf4q99n2bdknrc0000gn/T/form-init1595291808747030463.clj:2:49
>
> - call: public static java.lang.Object
> clojure.lang.Numbers.max(double,java.lang.Object).
>
> form-init1595291808747030463.clj:2 recur arg for primitive local: ret is
> not matching primitive, had: Object, needed: double
>
> Auto-boxing loop arg: ret
>
> Reflection warning,
> /private/var/folders/0k/xj_drd990xxf4q99n2bdknrc0000gn/T/form-init1595291808747030463.clj:2:3
>
> - call to static method alength on clojure.lang.RT can't be resolved
> (argument types: unknown).
>
> Boxed math warning,
> /private/var/folders/0k/xj_drd990xxf4q99n2bdknrc0000gn/T/form-init1595291808747030463.clj:2:3
>
> - call: public static boolean clojure.lang.Numbers.lt
> (long,java.lang.Object).
>
> Reflection warning,
> /private/var/folders/0k/xj_drd990xxf4q99n2bdknrc0000gn/T/form-init1595291808747030463.clj:2:58
>
> - call to static method aget on clojure.lang.RT can't be resolved (argument
> types: unknown, int).
>
> Boxed math warning,
> /private/var/folders/0k/xj_drd990xxf4q99n2bdknrc0000gn/T/form-init1595291808747030463.clj:2:49
>
> - call: public static java.lang.Object
> clojure.lang.Numbers.max(java.lang.Object,java.lang.Object).
>
>
>
> On Wednesday, June 10, 2015 at 4:07:09 PM UTC-4, Ritchie Cai wrote:
>>
>> I'm working on a java array of double with 1280000 elements. I need the
>> max and min values of the array. So I initially tried areduce and loop,
>> both gives runs around 20 seconds. But when try (apply max (vec array)) I
>> get result under 90 ms.
>> Can anyone explain why there is such a big difference?
>> Also if want to iterate large java array like this to do some other
>> operations, e.g. convolution, what's the best way to go? Is there another
>> fast way to iterate through array or do I need to convert array into vector?
>>
>> Thanks
>> Ritchie
>>
>>
--
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.