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.