On Fri, Jun 14, 2013 at 5:46 PM, Mikhail Kryshen <mikh...@kryshen.net> wrote: > JIT will probably remove unnecessary checkcast instructions. What looks > suspicious to me is that i and asize are converted to longs (notice i2l > opcodes). I noticed earlier that loops with long counters are measurably > slower for the same number of iterations (probably, HotSpot does not > apply some optimizations in this case).
That was my impression as well, but in this case it doesn't seem to happen, perhaps because the double array is reloaded every time within the loop so the JIT is not able to determine that the cast is redundant. Leon's experiments above seem to confirm this, because just removing the cast instruction is sufficient to achieve parity with Java performance. > > Leon Barrett <lbarr...@climate.com> writes: > >> 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 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/groups/opt_out. >> >> > > -- > Mikhail -- -- 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/groups/opt_out.