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.

Reply via email to