Yep, you are right, inspecting the byte code generated by the clojure code:
(loop [n 0] (when (< n 10000000) (-> (StringBuilder.) (.append n) (.append "another word") (.toString)) (recur (unchecked-inc n)))) It is: L4 LINENUMBER 4 L4 LLOAD 1 LDC 10000000 LCMP IFGE L5 L6 LINENUMBER 5 L6 L7 LINENUMBER 5 L7 L8 LINENUMBER 5 L8 NEW java/lang/StringBuilder DUP INVOKESPECIAL java/lang/StringBuilder.<init> ()V CHECKCAST java/lang/StringBuilder LLOAD 1 INVOKEVIRTUAL java/lang/StringBuilder.append (J)Ljava/lang/StringBuilder; CHECKCAST java/lang/StringBuilder LDC "another word" CHECKCAST java/lang/String INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder; CHECKCAST java/lang/StringBuilder INVOKEVIRTUAL java/lang/StringBuilder.toString ()Ljava/lang/String; POP L9 LINENUMBER 6 L9 LLOAD 1 LCONST_1 LADD LSTORE 1 GOTO L2 GOTO L10 L11 POP L5 ACONST_NULL It's almost the same with java compiled byte code,except using long type's instruments (LCMP and LADD etc) and some CHECKCAST (cast type) instruments. 2014-03-01 21:00 GMT+08:00 Jozef Wagner <jozef.wag...@gmail.com>: > Clojure math functions compile down to the same JVM 'instruction' as from > java. See http://galdolber.tumblr.com/post/77153377251/clojure-intrinsics > > > > On Sat, Mar 1, 2014 at 1:23 PM, dennis zhuang <killme2...@gmail.com>wrote: > >> I think the remaining overhead of clojure sample code is that operators >> in java such as '++' and '<" etc.They are just an instrument of JVM -- iinc >> and if_icmpge. But they are both functions in clojure,and they will be >> called by invokevirtual instrument.It cost much more performance. >> >> >> >> >> 2014-03-01 20:07 GMT+08:00 dennis zhuang <killme2...@gmail.com>: >> >> I forgot to note hat i test the java sample and clojure sample code with >>> the same jvm options '-server'. >>> >>> >>> >>> 2014-03-01 20:03 GMT+08:00 dennis zhuang <killme2...@gmail.com>: >>> >>> The "String a=i+"another word";" is also compiled into using >>>> StringBuilder, see the byte code by javap -v: >>>> >>>> Code: >>>> stack=5, locals=5, args_size=1 >>>> 0: invokestatic #2 // Method >>>> java/lang/System.nanoTime:()J >>>> 3: lstore_1 >>>> 4: iconst_0 >>>> 5: istore_3 >>>> 6: iload_3 >>>> 7: ldc #3 // int 10000000 >>>> 9: if_icmpge 39 >>>> 12: new #4 // class >>>> java/lang/StringBuilder >>>> 15: dup >>>> 16: invokespecial #5 // Method >>>> java/lang/StringBuilder."<init>":()V >>>> 19: iload_3 >>>> 20: invokevirtual #6 // Method >>>> java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; >>>> 23: ldc #7 // String another word >>>> 25: invokevirtual #8 // Method >>>> java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; >>>> 28: invokevirtual #9 // Method >>>> java/lang/StringBuilder.toString:()Ljava/lang/String; >>>> 31: astore 4 >>>> 33: iinc 3, 1 >>>> 36: goto 6 >>>> 39: getstatic #10 // Field >>>> java/lang/System.out:Ljava/io/PrintStream; >>>> 42: invokestatic #2 // Method >>>> java/lang/System.nanoTime:()J >>>> 45: lload_1 >>>> 46: lsub >>>> 47: l2d >>>> 48: ldc2_w #11 // double 1.0E9d >>>> 51: ddiv >>>> 52: invokevirtual #13 // Method >>>> java/io/PrintStream.println:(D)V >>>> >>>> >>>> I think the performance hotspot in this simple example is the object >>>> allocate/gc and function calling overhead.The str function create >>>> an anonymous function every time to concat argument strings: >>>> >>>> (^String [x & ys] >>>> ((fn [^StringBuilder sb more] >>>> (if more >>>> (recur (. sb (append (str (first more)))) (next more)) >>>> (str sb))) >>>> (new StringBuilder (str x)) ys))) >>>> >>>> And we all know that a function in clojure is a java object allocated >>>> in heap.And another overhead is calling the function,it's virtual method. >>>> >>>> By watching the gc statistics using 'jstat -gcutil <pid> 2000', i found >>>> that the clojure sample ran about 670 minor gc,but the java sample is only >>>> 120 minor gc. >>>> >>>> A improved clojure version,it's performance is closed to java sample: >>>> >>>> user=> (time (dotimes [n 10000000] (-> (StringBuilder.) (.append n) >>>> (.append "another word") (.toString)))) >>>> "Elapsed time: 1009.942 msecs" >>>> >>>> >>>> >>>> >>>> 2014-03-01 18:02 GMT+08:00 bob <wee....@gmail.com>: >>>> >>>> Case : >>>>> >>>>> clojure verison: >>>>> >>>>> (time (dotimes [n 10000000] (str n "another word"))) ;; take about >>>>> 5000msec >>>>> >>>>> java version >>>>> >>>>> long time = System.nanoTime(); >>>>> >>>>> for(int i=0 ; i<10000000 ;i++){ >>>>> String a=i+"another word"; >>>>> } >>>>> System.out.println(System.nanoTime()-time); >>>>> >>>>> >>>>> The java version take about 500 msecs, I thought it might be caused by >>>>> the str implementation which is using string builder, and it might not be >>>>> the best choice in the case of no much string to concat, and then I >>>>> replace >>>>> "another word" with 5 long strings as the parameter, however no surprise. >>>>> >>>>> I just wonder what make the difference, or how to find the difference. >>>>> >>>>> Thanks >>>>> >>>>> >>>>> >>>>> On Saturday, March 1, 2014 1:26:38 PM UTC+8, Shantanu Kumar wrote: >>>>>> >>>>>> I have seen (and I keep seeing) a ton of Java code that performs >>>>>> poorly. Empirically, it's equally easy to write a slow Java app. You >>>>>> always >>>>>> need a discerning programmer to get good performance from any >>>>>> language/tool. >>>>>> >>>>>> Numbers like 1/4 or 1/10 can be better discussed in presence of the >>>>>> use-cases and perf test cases. Most of the problems you listed can be >>>>>> mitigated by `-server` JIT, avoiding reflection, transients, loop-recur, >>>>>> arrays, perf libraries and some Java code. >>>>>> >>>>>> Shantanu >>>>>> >>>>> -- >>>>> 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. >>>>> >>>> >>>> >>>> >>>> -- >>>> 庄晓丹 >>>> Email: killme2...@gmail.com xzhu...@avos.com >>>> Site: http://fnil.net >>>> Twitter: @killme2008 >>>> >>>> >>>> >>> >>> >>> -- >>> 庄晓丹 >>> Email: killme2...@gmail.com xzhu...@avos.com >>> Site: http://fnil.net >>> Twitter: @killme2008 >>> >>> >>> >> >> >> -- >> 庄晓丹 >> Email: killme2...@gmail.com xzhu...@avos.com >> Site: http://fnil.net >> Twitter: @killme2008 >> >> >> -- >> 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. >> > > -- > 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. > -- 庄晓丹 Email: killme2...@gmail.com xzhu...@avos.com Site: http://fnil.net Twitter: @killme2008 -- 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.