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 <[email protected]>:
> 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 [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.
>
--
庄晓丹
Email: [email protected] [email protected]
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 [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.