Ridiculously massive slowdown when working with images

73 views
Skip to first unread message

Robert McIntyre

unread,
Jan 28, 2011, 10:48:44 AM1/28/11
to Clojure
I tried to convert this java code line for line to clojure to compare
the speed differences, and boy was I surprised!

public static void ConvertToAWT(byte[] cpuArray){
// Given an array of bytes representing a c-style bgra image,
// converts to a java style abgr image
int len = java.lang.reflect.Array.getLength(cpuArray);
for (int i = 0; i < len; i+=4){
byte b = cpuArray[i+0];
byte g = cpuArray[i+1];
byte r = cpuArray[i+2];
byte a = cpuArray[i+3];
cpuArray[i+0] = a;
cpuArray[i+1] = b;
cpuArray[i+2] = g;
cpuArray[i+3] = r; }}

(defn java-like []
(loop [i (int 0)] (if (< i buffer-size)
(let [ + clojure.core/unchecked-add
b (aget cpuArray i)
g (aget cpuArray (+ 1 i))
r (aget cpuArray (+ 2 i))
a (aget cpuArray (+ 3 i))]
(aset-byte cpuArray i a)
(aset-byte cpuArray (+ 1 i) b)
(aset-byte cpuArray (+ 2 i) g)
(aset-byte cpuArray (+ 3 i) r)
(recur (int (+ i 4)))))))

(defn clojure-like []
(doall (flatten (map (fn [[b g r a]] [a b g r]) (partition 4 4
cpuArray)))))


for a byte-array of size 1920000, the java-like clojure function, a
line for line translation, takes several minutes, while the java
method takes around 3 milliseconds.
the clojure-like one takes 6 seconds.

Why is the clojure function so much more obnoxiously slow than its
java counterpart?
Can anyone shed some light on what I'm doing wrong?

sincerely,
--Robert McIntyre

Ken Wesson

unread,
Jan 28, 2011, 10:55:11 AM1/28/11
to clo...@googlegroups.com

Boxing, most likely, and/or reflection. Your cpuArray needs to be
produced with (int-array ...) and hinted with ^ints to get top
performance.

David Nolen

unread,
Jan 28, 2011, 11:06:14 AM1/28/11
to clo...@googlegroups.com
On Fri, Jan 28, 2011 at 10:48 AM, Robert McIntyre <r...@mit.edu> wrote:
I'm assuming you're using 1.2.0. cpuArray needs to be hinted. All the literals also need to be hinted. Don't use aset-byte, use aset.

In 1.3.0 you no longer have to hint the literals and you can use the *unchecked-math* compiler flag instead of redefining unchecked-add as a local.

David

Benny Tsai

unread,
Jan 28, 2011, 12:55:42 PM1/28/11
to Clojure
Combining Ken and David's tips, this version processes a byte-array of
sizd 1920000 in about 13 milliseconds on my machine:

(def buffer-size 1920000)
(def array (byte-array buffer-size))

(defn java-like [^bytes cpuArray]
(loop [i (int 0)]
(if (< i buffer-size)
(let [b (aget cpuArray i)
g (aget cpuArray (unchecked-add i (int 1)))
r (aget cpuArray (unchecked-add i (int 2)))
a (aget cpuArray (unchecked-add i (int 3)))]
(aset cpuArray i a)
(aset cpuArray (unchecked-add i (int 1)) b)
(aset cpuArray (unchecked-add i (int 2)) g)
(aset cpuArray (unchecked-add i (int 3)) r)
(recur (unchecked-add i (int 4)))))))

user=> (time (java-like array))
"Elapsed time: 13.648662 msecs"

Found something interesting when I tried to emulate how Robert's
version aliased 'unchecked-add' as '+':

(defn java-like [^bytes cpuArray]
(loop [i (int 0)]
(if (< i buffer-size)
(let [+ unchecked-add
b (aget cpuArray i)
g (aget cpuArray (+ i (int 1)))
r (aget cpuArray (+ i (int 2)))
a (aget cpuArray (+ i (int 3)))]
(aset cpuArray i a)
(aset cpuArray (+ i (int 1)) b)
(aset cpuArray (+ i (int 2)) g)
(aset cpuArray (+ i (int 3)) r)
(recur (+ i (int 4)))))))

When I try to compile this, Clojure complains that I'm trying to
rebind i, a primitive local, with a value of the wront type in
'recur'.

It seems that 'unchecked-add' returns a primitive (note that in the
first version, 'recur' happily accepts the return from 'unchecked-add'
without coercion), but when 'unchecked-add' is bound to a new name,
the return gets boxed.

Is this the correct interpretation, or am I missing something?

Ken Wesson

unread,
Jan 28, 2011, 1:07:41 PM1/28/11
to clo...@googlegroups.com
On Fri, Jan 28, 2011 at 12:55 PM, Benny Tsai <benny...@gmail.com> wrote:
> It seems that 'unchecked-add' returns a primitive (note that in the
> first version, 'recur' happily accepts the return from 'unchecked-add'
> without coercion), but when 'unchecked-add' is bound to a new name,
> the return gets boxed.
>
> Is this the correct interpretation, or am I missing something?

It's correct. Clojure's compiler inlines certain functions, including
clojure.core/unchecked-foo and, when the arity is 2, clojure.core/+ --
but not a bare, un-qualified +, which might (or might not) at runtime
refer to clojure.core/+ or clojure.core/unchecked-add or whatever.

Robert McIntyre

unread,
Jan 28, 2011, 1:31:39 PM1/28/11
to clo...@googlegroups.com
And the plot thickens:

This:

(defn convert-image [#^bytes cpuArray]
(let [unchecked-add clojure.core/unchecked-add
len (int (count cpuArray))]
(loop [i (int 0)] (if (< i len)
(let [
b (byte (aget cpuArray i))
g (byte (aget cpuArray (unchecked-add 1
i)))
r (byte (aget cpuArray (unchecked-add 2
i)))
a (byte (aget cpuArray (unchecked-add 3
i)))]
(aset-byte cpuArray i a)
(aset-byte cpuArray (unchecked-add 1 i) b)
(aset-byte cpuArray (unchecked-add 2 i) g)
(aset-byte cpuArray (unchecked-add 3 i) r)
(recur (int (unchecked-add i 4))))))))

vs this.


(defn convert-image [#^bytes cpuArray]
(let [len (java.lang.reflect.Array/getLength cpuArray)]
(loop [i (int 0)] (if (< i len)
(let [i2 (unchecked-add 1 i)
i3 (unchecked-add 2 i)
i4 (unchecked-add 3 i)
b (byte (aget cpuArray i))
g (byte (aget cpuArray i2))
r (byte (aget cpuArray i3))
a (byte (aget cpuArray i4))]
(aset-byte cpuArray i a)
(aset-byte cpuArray i2 b)
(aset-byte cpuArray i3 g)
(aset-byte cpuArray i4 r)
(recur (unchecked-add i 4)))))))

The first function takes forever; the second MUCH faster.
Upon disassembling the byte-code of the two compiled functions, it
does seem like the + was not being inlined.
Since the method of reassignment doesn't preserve the metadata, this
makes sense.

However, my new, modified function is still around 20 times slower
than the java version :(

I still don't understand what's slowing me down, but I'm much happier
that I can get within 20x of java instead of 20000x

thanks everyone.

sincerely,
--Robert McIntyre

> --
> 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

David Nolen

unread,
Jan 28, 2011, 1:55:00 PM1/28/11
to clo...@googlegroups.com
(ns atest)

(set! *warn-on-reflection* true)

(def buffer-size 1920000)
(def array (byte-array buffer-size))
(defn java-like [^bytes cpuArray]
  (loop [i (int 0)]
    (if (< i (int buffer-size))
      (let [b (byte (aget cpuArray i))
            g (byte (aget cpuArray (unchecked-add i (int 1))))
            r (byte (aget cpuArray (unchecked-add i (int 2))))
            a (byte (aget cpuArray (unchecked-add i (int 3))))]
        (aset cpuArray i a)
        (aset cpuArray (unchecked-add i (int 1)) b)
        (aset cpuArray (unchecked-add i (int 2)) g)
        (aset cpuArray (unchecked-add i (int 3)) r)
        (recur (unchecked-add i (int 4)))))))

(dotimes [_ 10]
  (time
   (dotimes [_ 1]
     (java-like array))))

On my machine this takes 9ms.

As a comparison, the following accomplishes the same thing in 1.3.0.

(ns test)

(set! *unchecked-math* true)
(set! *warn-on-reflection* true)

(def buffer-size 1920000)
(def array (byte-array buffer-size))
(defn java-like [^bytes cpuArray]
 (loop [i (int 0)]
   (if (< i buffer-size)
     (let [b (aget cpuArray i)
           g (aget cpuArray (+ i 1))
           r (aget cpuArray (+ i 2))
           a (aget cpuArray (+ i 3))]
       (aset cpuArray i a)
       (aset cpuArray (+ i 1) b)
       (aset cpuArray (+ i 2) g)
       (aset cpuArray (+ i 3) r)
       (recur (+ i 4))))))

(dotimes [_ 10]
  (time
   (dotimes [_ 1]
     (java-like array))))

Benny Tsai

unread,
Jan 28, 2011, 1:59:14 PM1/28/11
to Clojure
Try replacing 'aset-byte' with 'aset' and hinting all literals (change
1 to (int 1), etc.) as per David's suggestions. That should reduce
the gap even further.
> On Fri, Jan 28, 2011 at 1:07 PM, Ken Wesson <kwess...@gmail.com> wrote:

Aaron Cohen

unread,
Jan 28, 2011, 2:01:08 PM1/28/11
to clo...@googlegroups.com
On Fri, Jan 28, 2011 at 1:55 PM, David Nolen <dnolen...@gmail.com> wrote:
> As a comparison, the following accomplishes the same thing in 1.3.0.
> (ns test)
> (set! *unchecked-math* true)
> (set! *warn-on-reflection* true)
> (def buffer-size 1920000)
> (def array (byte-array buffer-size))
> (defn java-like [^bytes cpuArray]
>  (loop [i (int 0)]

Is this hint still necessary on 1.3.0?

Benny Tsai

unread,
Jan 28, 2011, 2:05:43 PM1/28/11
to Clojure
Ah I see. Thank you Ken.

On Jan 28, 11:07 am, Ken Wesson <kwess...@gmail.com> wrote:

David Nolen

unread,
Jan 28, 2011, 2:11:38 PM1/28/11
to clo...@googlegroups.com
The int cast on 0 was an oversight on my part. It's not necessary.

David 

Robert McIntyre

unread,
Jan 28, 2011, 2:36:52 PM1/28/11
to clo...@googlegroups.com
David, thanks for your suggestions.

I copied your code and tested it out, but on my machine it takes 230
milliseconds while the java version takes about 3.

If it's not too much trouble, how long does the java implementation
take on your machine?

sincerely,
--Robert McIntyre

David Nolen

unread,
Jan 28, 2011, 3:30:25 PM1/28/11
to clo...@googlegroups.com
On Fri, Jan 28, 2011 at 2:36 PM, Robert McIntyre <r...@mit.edu> wrote:
David, thanks for your suggestions.

I copied your code and tested it out, but on my machine it takes 230
milliseconds while the java version takes about 3.

If it's not too much trouble, how long does the java implementation
take on your machine?

sincerely,
--Robert McIntyre

The Java version takes about 0.65ms for me. If I switch the Java loop operations to be long arithmetic, the Java version takes 1.1ms-1.2ms. The Clojure version under 1.3.0 takes 8ms.

David

Benny Tsai

unread,
Jan 28, 2011, 4:24:20 PM1/28/11
to Clojure
Hi Robert,

Just out of curiosity, are you running Clojure with the -server
option? When I run David's code, -server mode cuts the time for the
first run by half, and the time for subsequent runs by a factor of 5.

On Jan 28, 12:36 pm, Robert McIntyre <r...@mit.edu> wrote:
> David, thanks for your suggestions.
>
> I copied your code and tested it out, but on my machine it takes 230
> milliseconds while the java version takes about 3.
>
> If it's not too much trouble, how long does the java implementation
> take on your machine?
>
> sincerely,
> --Robert McIntyre
>
>
>
>
>
>
>
> On Fri, Jan 28, 2011 at 2:11 PM, David Nolen <dnolen.li...@gmail.com> wrote:
> > On Fri, Jan 28, 2011 at 2:01 PM, Aaron Cohen <aa...@assonance.org> wrote:
>
> >> On Fri, Jan 28, 2011 at 1:55 PM, David Nolen <dnolen.li...@gmail.com>

Robert McIntyre

unread,
Jan 28, 2011, 8:16:42 PM1/28/11
to clo...@googlegroups.com
I'm running my JVM with:

-verbose:gc -Xmn500M -Xms2000M -Xmx2000M -server


sincerely,
--Robert McIntyre

Benny Tsai

unread,
Jan 29, 2011, 1:43:37 AM1/29/11
to Clojure
On my home computer, using the same options, the java version runs in
1.5 milliseconds, and David's 1.2 Clojure version in 16 milliseconds.
I'm at a loss as to why you're still seeing such a large gap between
the two versions.

Bill James

unread,
Jan 29, 2011, 1:56:11 AM1/29/11
to Clojure


On Jan 28, 12:55 pm, David Nolen <dnolen.li...@gmail.com> wrote:
> (ns atest)
>
> (set! *warn-on-reflection* true)
>
> (def buffer-size 1920000)
> (def array (byte-array buffer-size))
> (defn java-like [^bytes cpuArray]
>   (loop [i (int 0)]
>     (if (< i (int buffer-size))
>       (let [b (byte (aget cpuArray i))
>             g (byte (aget cpuArray (unchecked-add i (int 1))))
>             r (byte (aget cpuArray (unchecked-add i (int 2))))
>             a (byte (aget cpuArray (unchecked-add i (int 3))))]
>         (aset cpuArray i a)
>         (aset cpuArray (unchecked-add i (int 1)) b)
>         (aset cpuArray (unchecked-add i (int 2)) g)
>         (aset cpuArray (unchecked-add i (int 3)) r)
>         (recur (unchecked-add i (int 4)))))))
>
> (dotimes [_ 10]
>   (time
>    (dotimes [_ 1]
>      (java-like array))))
>

On my laptop, removing the "byte" hint speeds it up.
(I don't have the server version of Java.)


(set! *warn-on-reflection* true)

(def buffer-size 1920000)
(def array (byte-array buffer-size))

(defmacro add [m n] (list 'unchecked-add `(int ~m) `(int ~n)))

(defn java-like [^bytes cpu_array]
(loop [i (int 0)]
(if (< i (int buffer-size))
(let [b (aget cpu_array i)
g (aget cpu_array (add i 1))
r (aget cpu_array (add i 2))
a (aget cpu_array (add i 3))]
(aset cpu_array i a)
(aset cpu_array (add i 1) b)
(aset cpu_array (add i 2) g)
(aset cpu_array (add i 3) r)
(recur (int (add i 4)))))))

GrumpyLittleTed

unread,
Jan 29, 2011, 10:37:44 AM1/29/11
to Clojure
Part of the difference (under 1.2) is due to the (substantial)
overhead of accessing the buffer-size var on every iteration.

I ran a quick check and using David's version of the code result
averaged 17.2ms. Just changing buffer-size to a local with using (let
[buffer-size (int 1920000)]...) the time dropped to an average 3.4ms.

Bill James

unread,
Jan 29, 2011, 2:22:05 PM1/29/11
to Clojure


On Jan 28, 12:55 pm, David Nolen <dnolen.li...@gmail.com> wrote:
Faster than my previous post:

(set! *warn-on-reflection* true)

(def buffer-size 1920000)
(def array (byte-array buffer-size))

(defmacro add [m n] (list `unchecked-add `(int ~m) `(int ~n)))

(defn java-like [^bytes cpu_array]
(loop [i (int 0)]
(if (< i (int buffer-size))
(let [ i2 (add i 1)
i3 (add i 2)
i4 (add i 3)
b (aget cpu_array i)
g (aget cpu_array i2)
r (aget cpu_array i3)
a (aget cpu_array i4)
]
(aset cpu_array i a)
(aset cpu_array i2 b)
(aset cpu_array i3 g)
(aset cpu_array i4 r)
(recur (add i 4))))))

Bill James

unread,
Jan 29, 2011, 10:09:05 PM1/29/11
to Clojure
Another slight speed-up:

(set! *warn-on-reflection* true)

(def buffer-size 1920000)
(def array (byte-array buffer-size))

(defmacro add [m n] `(unchecked-add (int ~m) (int ~n)))
(defmacro amove[a i j] `(aset ~a ~j (aget ~a ~i)))

(defn java-like [^bytes cpu_array]
(loop [i (int 0)]
(if (< i (int buffer-size))
(let [ i2 (add i 1)
i3 (add i 2)
i4 (add i 3)
a (aget cpu_array i4)
]
(amove cpu_array i3 i4)
(amove cpu_array i2 i3)
(amove cpu_array i i2)
(aset cpu_array i a)
(recur (add i 4))))))

Bill James

unread,
Jan 30, 2011, 10:15:28 AM1/30/11
to Clojure
GrumpyLittleTed wrote:
> Part of the difference (under 1.2) is due to the (substantial)
> overhead of accessing the buffer-size var on every iteration.
>
> I ran a quick check and using David's version of the code result
> averaged 17.2ms. Just changing buffer-size to a local with using (let
> [buffer-size (int 1920000)]...) the time dropped to an average 3.4ms.
>

Great! Now I remember that that same technique is used in Lua.
See long this version takes.

(set! *warn-on-reflection* true)

(def buffer-size 1920000)
(def array (byte-array buffer-size))

(defmacro add [m n] `(unchecked-add (int ~m) (int ~n)))
(defmacro amove[a i j] `(aset ~a ~j (aget ~a ~i)))

(defn java-like [^bytes cpu_array]
(let [buffer-size (int buffer-size)]
(loop [i (int 0)]
(if (< i buffer-size)
(let [ i2 (add i 1)
i3 (add i 2)
i4 (add i 3)
a (aget cpu_array i4)
]
(amove cpu_array i3 i4)
(amove cpu_array i2 i3)
(amove cpu_array i i2)
(aset cpu_array i a)
(recur (add i 4)))))))

David Nolen

unread,
Jan 30, 2011, 1:01:23 PM1/30/11
to clo...@googlegroups.com
On Sat, Jan 29, 2011 at 10:37 AM, GrumpyLittleTed <grumpyl...@gmail.com> wrote:
Part of the difference (under 1.2) is due to the (substantial)
overhead of accessing the buffer-size var on every iteration.

I ran a quick check and using David's version of the code result
averaged 17.2ms. Just changing buffer-size to a local with using (let
[buffer-size (int 1920000)]...) the time dropped to an average 3.4ms.

Yes, putting buffer-size in a let makes the performance in 1.3.0 identical to Java with long loop arithmetic.

David 

Robert McIntyre

unread,
Jan 30, 2011, 2:48:12 PM1/30/11
to clo...@googlegroups.com
That's excellent. Thank you everyone.

Maybe someone could compile all these "let's speed up this clojure
code" threads and put it somewhere as a valuable resource we could
point to when things like this come up again?

sincerely,
--Robert McIntyre

Benny Tsai

unread,
Jan 30, 2011, 7:24:59 PM1/30/11
to Clojure
Nice! That version runs in 6 milliseconds on my machine, fastest of
all the code posted so far. One more idea: use 'unchecked-inc'
instead of 'unchecked-add'. This takes it under 3 milliseconds in my
tests.

(defn java-like [^bytes cpu_array]
(let [buffer-size (int buffer-size)]
(loop [i (int 0)]
(if (< i buffer-size)
(let [i2 (unchecked-inc i)
i3 (unchecked-inc i2)
i4 (unchecked-inc i3)
a (aget cpu_array i4)]
(amove cpu_array i3 i4)
(amove cpu_array i2 i3)
(amove cpu_array i i2)
(aset cpu_array i a)
(recur (unchecked-inc i4)))))))

Bill James

unread,
Jan 31, 2011, 2:00:59 AM1/31/11
to Clojure
Benny Tsai wrote:
> Nice! That version runs in 6 milliseconds on my machine, fastest of
> all the code posted so far. One more idea: use 'unchecked-inc'
> instead of 'unchecked-add'. This takes it under 3 milliseconds in my
> tests.
>
> (defn java-like [^bytes cpu_array]
> (let [buffer-size (int buffer-size)]
> (loop [i (int 0)]
> (if (< i buffer-size)
> (let [i2 (unchecked-inc i)
> i3 (unchecked-inc i2)
> i4 (unchecked-inc i3)
> a (aget cpu_array i4)]
> (amove cpu_array i3 i4)
> (amove cpu_array i2 i3)
> (amove cpu_array i i2)
> (aset cpu_array i a)
> (recur (unchecked-inc i4)))))))
>

Yes, that speeds it up considerably. If I can get Java server
installed
on my machine, I'll post some timings.

B Smith-Mannschott

unread,
Jan 31, 2011, 6:46:49 AM1/31/11
to clo...@googlegroups.com

What is this "java server" of which you speak. In JVMs I'm familiar
with (Sun/Oracle, OpenJDK) it's just a matter of passing the option
-server to java when starting it.

// Ben

Bill James

unread,
Jan 31, 2011, 2:33:43 PM1/31/11
to Clojure


On Jan 31, 5:46 am, B Smith-Mannschott <bsmith.o...@gmail.com> wrote:

> > Yes, that speeds it up considerably.  If I can get Java server
> > installed
> > on my machine, I'll post some timings.
>
> What is this "java server" of which you speak.  In JVMs I'm familiar
> with (Sun/Oracle, OpenJDK) it's just a matter of passing the option
> -server to java when starting it.
>
> // Ben

Usually Windoze doesn't have the Java server executable.
You have to download the Java JDK.

Bill James

unread,
Jan 31, 2011, 2:40:52 PM1/31/11
to Clojure
(set! *warn-on-reflection* true)

(def buffer-size 1920000)
(def array (byte-array buffer-size))

(defmacro add [m n] `(unchecked-add (int ~m) (int ~n)))
(defmacro uinc [m] `(unchecked-inc ~m))
(defmacro amove[a i j] `(aset ~a ~j (aget ~a ~i)))


(defn java-like0 [^bytes cpu_array]
(loop [i (int 0)]
(if (< i (int buffer-size))
(let [b (byte (aget cpu_array i))
g (byte (aget cpu_array (unchecked-add i (int 1))))
r (byte (aget cpu_array (unchecked-add i (int 2))))
a (byte (aget cpu_array (unchecked-add i (int 3))))]
(aset cpu_array i a)
(aset cpu_array (unchecked-add i (int 1)) b)
(aset cpu_array (unchecked-add i (int 2)) g)
(aset cpu_array (unchecked-add i (int 3)) r)
(recur (unchecked-add i (int 4)))))))


;;; Make buffer-size a local.
(defn java-like1 [^bytes cpu_array]
(let [buffer-size (int buffer-size)]
(loop [i (int 0)]
(if (< i (int buffer-size))
(let [b (byte (aget cpu_array i))
g (byte (aget cpu_array (unchecked-add i (int 1))))
r (byte (aget cpu_array (unchecked-add i (int 2))))
a (byte (aget cpu_array (unchecked-add i (int 3))))]
(aset cpu_array i a)
(aset cpu_array (unchecked-add i (int 1)) b)
(aset cpu_array (unchecked-add i (int 2)) g)
(aset cpu_array (unchecked-add i (int 3)) r)
(recur (unchecked-add i (int 4))))))))


;;; Move byte directly from array[i] to array[j].
;;; Assign index values to local variables.
;;; Eliminate "byte" hint.
(defn java-like2 [^bytes cpu_array]
(let [buffer-size (int buffer-size)]
(loop [i (int 0)]
(if (< i buffer-size)
(let [ i2 (add i 1)
i3 (add i 2)
i4 (add i 3)
a (aget cpu_array i4)
]
(amove cpu_array i3 i4)
(amove cpu_array i2 i3)
(amove cpu_array i i2)
(aset cpu_array i a)
(recur (add i 4)))))))


;;; Use unchecked-inc instead of unchecked-add.
(defn java-like3 [^bytes cpu_array]
(let [buffer-size (int buffer-size)]
(loop [i (int 0)]
(if (< i buffer-size)
(let [ i2 (uinc i)
i3 (uinc i2)
i4 (uinc i3)
a (aget cpu_array i4)
]
(amove cpu_array i3 i4)
(amove cpu_array i2 i3)
(amove cpu_array i i2)
(aset cpu_array i a)
(recur (uinc i4)))))))



(dotimes [i 4]
(let [func-name (str "java-like" i)
func (resolve (symbol func-name))]
(println func-name)
(dotimes [_ 7]
(time
(func array)))))


I think it will be faster on my laptop, but for now here are
the results on a rather old desktop.

Clojure 1.2; Java 1.5.0_07 (server); Pentium 4 3.2GHz (2 cores)

java-like0
"Elapsed time: 81.954298 msecs"
"Elapsed time: 24.381966 msecs"
"Elapsed time: 16.528463 msecs"
"Elapsed time: 12.656007 msecs"
"Elapsed time: 12.666522 msecs"
"Elapsed time: 13.240584 msecs"
"Elapsed time: 12.625828 msecs"
java-like1
"Elapsed time: 56.773426 msecs"
"Elapsed time: 19.099019 msecs"
"Elapsed time: 16.669669 msecs"
"Elapsed time: 6.325035 msecs"
"Elapsed time: 6.400674 msecs"
"Elapsed time: 6.374463 msecs"
"Elapsed time: 6.266154 msecs"
java-like2
"Elapsed time: 46.777715 msecs"
"Elapsed time: 11.840942 msecs"
"Elapsed time: 10.842774 msecs"
"Elapsed time: 5.56714 msecs"
"Elapsed time: 5.655566 msecs"
"Elapsed time: 5.611824 msecs"
"Elapsed time: 5.509589 msecs"
java-like3
"Elapsed time: 37.785107 msecs"
"Elapsed time: 8.711968 msecs"
"Elapsed time: 8.377959 msecs"
"Elapsed time: 7.094104 msecs"
"Elapsed time: 3.637105 msecs"
"Elapsed time: 3.757499 msecs"
"Elapsed time: 3.589582 msecs"

Bill James

unread,
Jan 31, 2011, 7:33:10 PM1/31/11
to Clojure
Much faster on my laptop.
Core2 Duo P8600 2.4GHz
Clojure 1.2
java version "1.6.0"
Java(TM) SE Runtime Environment (build 1.6.0-b105)
Java HotSpot(TM) Server VM (build 1.6.0-b105, mixed mode)

java-like0
"Elapsed time: 40.007319 msecs"
"Elapsed time: 11.8015 msecs"
"Elapsed time: 10.262477 msecs"
"Elapsed time: 10.363887 msecs"
"Elapsed time: 10.242364 msecs"
"Elapsed time: 10.163024 msecs"
"Elapsed time: 10.518935 msecs"
java-like1
"Elapsed time: 36.042849 msecs"
"Elapsed time: 8.833804 msecs"
"Elapsed time: 8.630427 msecs"
"Elapsed time: 8.084827 msecs"
"Elapsed time: 8.001296 msecs"
"Elapsed time: 8.166401 msecs"
"Elapsed time: 8.024763 msecs"
java-like2
"Elapsed time: 24.401704 msecs"
"Elapsed time: 4.934146 msecs"
"Elapsed time: 4.368991 msecs"
"Elapsed time: 4.326248 msecs"
"Elapsed time: 4.326248 msecs"
"Elapsed time: 4.328203 msecs"
"Elapsed time: 4.288813 msecs"
java-like3
"Elapsed time: 18.028548 msecs"
"Elapsed time: 1.968686 msecs"
"Elapsed time: 1.94494 msecs"
"Elapsed time: 0.991746 msecs"
"Elapsed time: 0.942299 msecs"
"Elapsed time: 0.936153 msecs"
"Elapsed time: 0.935873 msecs"


Less than 1 millisecond!
We are the winning team!

Bill James

unread,
Feb 1, 2011, 12:10:08 AM2/1/11
to Clojure
More precisely, the missing file is
C:\Program Files\Java\jre6\bin\server\jvm.dll
Reply all
Reply to author
Forward
0 new messages