Hi. I've been working with people at Prismatic to optimize some simple math
code in Clojure. However, it seems that Clojure generates an unnecessary
type check that slows our (otherwise-optimized) code by 50%. Is there a
good way to avoid this, is it a bug in Clojure 1.5.1, or something else?
What should I do to work around this?
Here's my example. The aget seems to generate an unnecessary checkcastbytecode.
I used Jasper and Jasmin to decompile and recompile Bar.class
into Bar_EDITED.class, without that bytecode. The edited version takes
about 2/3 the time.
(ns demo
(:import demo.Bar_EDITED))
(definterface Foo
(arraysum ^double [^doubles a ^int i ^int asize ^double sum]))
(deftype Bar []
Foo
(arraysum ^double [this ^doubles a ^int i ^int asize ^double sum]
(if (< i asize)
(recur a (unchecked-inc-int i) asize (+ sum (aget a i)))
sum)))
(defn -main [& args]
(let [bar (Bar.)
bar-edited (Bar_EDITED.)
asize 10000
a (double-array asize)
i 0
ntimes 10000]
(time
(dotimes [iter ntimes]
(.arraysum bar a i asize 0)))
(time
(dotimes [iter ntimes]
(.arraysum bar-edited a i asize 0)))))
;; $ lein2 run -m demo
;; Compiling demo
;; "Elapsed time: 191.015885 msecs"
;; "Elapsed time: 129.332 msecs"
Here's the bytecode for Bar.arraysum:
public java.lang.Object arraysum(double[], int, int, double);
Code:
0: iload_2
1: i2l
2: iload_3
3: i2l
4: lcmp
5: ifge 39
8: aload_1
9: iload_2
10: iconst_1
11: iadd
12: iload_3
13: dload 4
15: aload_1
16: aconst_null
17: astore_1
18: checkcast #60 // class "[D"
21: iload_2
22: invokestatic #64 // Method
clojure/lang/RT.intCast:(I)I
25: daload
26: dadd
27: dstore 4
29: istore_3
30: istore_2
31: astore_1
32: goto 0
35: goto 44
38: pop
39: dload 4
41: invokestatic #70 // Method
java/lang/Double.valueOf:(D)Ljava/lang/Double;
44: areturn
As far as I can tell, Clojure generated a checkcast opcode that tests on
every loop to make sure the double array is really a double array. When I
remove that checkcast, I get a 1/3 speedup (meaning it's a 50% overhead).
Can someone help me figure out how to avoid this overhead?
Thanks.
- Leon Barrett
--
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
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 [email protected].
For more options, visit https://groups.google.com/groups/opt_out.