fast reduce

159 views
Skip to first unread message

Yehonathan Sharvit

unread,
Apr 7, 2014, 5:26:36 PM4/7/14
to clojur...@googlegroups.com
The performance of array iteration in cljs is not good compared vs. native iteration on js array.
For example, I would like to sum all the members of on array.

I have tried (apply + arr) and (doseq ...). See below.


Is there a way to improve my code?


(def arr (range 20480))

(set! js/arr (clj->js arr))


(js/eval "function sum(arr) {
var total = 0,
i;
for (i = 0; i < arr.length; i++) {
total += arr[i];
}
return total;
}")


(defn my-sum[a]
(def res 0)
(doseq [x a]
(set! res (+ res x )))
res)


(time (js/sum js/arr)) ; less than 1 msec
(time (apply + arr)); around 10 msec
(time (my-sum arr)); around 10 msec

David Nolen

unread,
Apr 7, 2014, 5:38:36 PM4/7/14
to clojur...@googlegroups.com
On Mon, Apr 7, 2014 at 5:26 PM, Yehonathan Sharvit <vie...@gmail.com> wrote:
(defn my-sum[a]
  (def res 0)
  (doseq [x a]
    (set! res (+ res x )))
  res)

def's are always top-level. Do not put def's in def's like this.

(defn my-sum [a]
  (loop [i 0 sum 0]
    (if (< i (alength a))
      (recur (inc i) (+ sum (aget a i))
      sum)))

Should give similar performance to the version you wrote in JavaScript.

David

Yehonathan Sharvit

unread,
Apr 8, 2014, 2:44:30 AM4/8/14
to clojur...@googlegroups.com
Thanks David!

I see that ClojureScript can deal with js arrays both with:
1. aget and alength
2. get and count

The first option is much much faster!!!




--
Note that posts from new members are moderated - please be patient with your first post.
---
You received this message because you are subscribed to a topic in the Google Groups "ClojureScript" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojurescript/ex2GmRMQCXQ/unsubscribe.
To unsubscribe from this group and all its topics, send an email to clojurescrip...@googlegroups.com.
To post to this group, send email to clojur...@googlegroups.com.
Visit this group at http://groups.google.com/group/clojurescript.



--
"Are we what we become or do we become what we are?" - Prof. Beno Gross

Yehonathan Sharvit

unread,
Apr 8, 2014, 3:01:47 PM4/8/14
to clojur...@googlegroups.com
I have discovered that areduce is also very fast:

(areduce a i res 0 (+ res (aget a i)))

I feel that it preserves the functional programming spirit.

Any comment on that, David?

David Nolen

unread,
Apr 8, 2014, 3:02:30 PM4/8/14
to clojur...@googlegroups.com
Yes areduce is preferred if applicable.

David


You received this message because you are subscribed to the Google Groups "ClojureScript" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojurescrip...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages