Amap vs Map performance

147 views
Skip to first unread message

Rubén Béjar

unread,
Jul 8, 2010, 12:12:39 PM7/8/10
to clo...@googlegroups.com
Hi all,

I have found again some time for Clojure, so I am back trying
to solve my problems with the perfomance of my toy cellular
automata. I have been trying to use Java arrays and type hints,
with a small success, but I have found that
amap for arrays seems terribly slower than map for vectors,
and that is troubling me a little.

For instance, if I try this simple code:

------------------------------------------------------------------------------
(def an-array (int-array 25000 (int 0)))
(time (amap an-array idx ret (+ (int 1) (aget an-array idx))))

(def a-vec (vec (int-array 25000 (int 0))))
(time (dorun (map #(+ % (int 1)) a-vec)))
------------------------------------------------------------------------------

A typical result is:

------------------------------------------------------------------------------
Clojure 1.2.0-master-SNAPSHOT
"Elapsed time: 2226.685713 msecs"
"Elapsed time: 16.006892 msecs"
------------------------------------------------------------------------------

As far as I understand what I am doing, they do the same;
in the first case with a Java array of ints, and in the
second case with a Clojure vector of ints. The dorun in the
second case would prevent me from making the
mistake of measuring the performance of a lazy
operation.

Nevertheless, map seems hundreds of times faster.
Is this normal? Am I doing something wrong? I expected
that amap was faster than map, or at least not that
slower...


Thanks,

  Rubén


P.S. 
David, thanks for your code. It looks good and performs
very well too. I will study it in more detail when I start learning about
protocols. For now, I am styill trying to replicate its performance my
way :-)

David Nolen wrote:

Because I like sitting around optimizing Clojure code I looked into this some more:


With the really great changes in the 1.2, you can see there's a lovely lack of manual type hinting here. No macros required either. On my machine this averages around ~30ms for 500x500. Not too shabby. 2000x2000 takes ~480ms or so.

David

Rubén BÉJAR HERNÁNDEZ

Dpto. de Informática e Ingeniería de Sistemas - Universidad de Zaragoza
(Computing and Systems Engineering Department - Universidad de Zaragoza)
c/ María de Luna 1, 50018 Zaragoza, Spain

Tel: (+34) 976 76 2332 (Fax: 1914)  
rbe...@unizar.es
http://iaaa.cps.unizar.es
Follow me on Twitter

twitter.png

Nicolas Oury

unread,
Jul 8, 2010, 2:25:03 PM7/8/10
to clo...@googlegroups.com
It seems to be a problem with 1.2.
I have 28ms in 1.1 and 4000ms in 1.2.


--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@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+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

twitter.png

Harvey Hirst

unread,
Jul 8, 2010, 11:10:10 PM7/8/10
to clo...@googlegroups.com
With 1.2:

(set! *warn-on-reflection* true)
(time (amap an-array idx ret (+ (int 1) (aget an-array idx))))
Reflection warning, NO_SOURCE_PATH:52 - call to aclone can't be resolved.
Reflection warning, NO_SOURCE_PATH:52 - call to alength can't be resolved.
Reflection warning, NO_SOURCE_PATH:52 - call to aget can't be resolved.
Reflection warning, NO_SOURCE_PATH:52 - call to aset can't be resolved.
"Elapsed time: 2663.612 msecs"

Type hinting the arrays:
(time (amap ^ints an-array idx ret (+ (int 1) (aget ^ints an-array idx))))
"Elapsed time: 11.443 msecs"

Whenever you see unusually slow performance reflection is frequently the cause.
Not sure about the 1.1/1.2 performance though.

Harvey
-- 
"You're keeping me alive because you don't know DOS?"
Izzy, Prophecy II

nickikt

unread,
Jul 9, 2010, 2:17:36 AM7/9/10
to Clojure
Hi all,

I'm running Clojure 1.1

(def an-array (int-array 25000 (int 0)))
(time (amap an-array idx ret (+ (int 1) (aget an-array idx))))
"Elapsed time: 50.83188 msecs"

(def a-vec (vec (int-array 25000 (int 0))))
(time (dorun (map #(+ % (int 1)) a-vec)))
"Elapsed time: 17.392434 msecs"

So arrays are slower here to but not that bad.
Reply all
Reply to author
Forward
0 new messages