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 <[email protected]>:
> 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 <[email protected]>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 <[email protected]>:
>>
>> 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 <[email protected]>:
>>>
>>> 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
>>>>
>>>>
>>>>
>>>
>>>
>>> --
>>> 庄晓丹
>>> Email: [email protected] [email protected]
>>> Site: http://fnil.net
>>> Twitter: @killme2008
>>>
>>>
>>>
>>
>>
>> --
>> 庄晓丹
>> 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.
>>
>
> --
> 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.