Thursday, July 26, 2012

What's happening in the JVM level when you concatenate the Strings?


  Have you ever been told by someone about concatenate Strings in Java? Of course, there are many ways to do it but, what is the difference between each approach?

  In this blog post, I disassemble the example Java bytecodes (.class files) into Jasmin (simple assembler-like syntax with JVM instruction set). Each example demonstrates the different way to concatenate Strings(but not cover all the ways that exist in the world ^^).

Lets' disassemble and see what will be happened in the JVM level !

Note: I'm using JasminParser as a disassembler tool.


·         Concatenate Strings using '+' sing.

Java code

public void concatStrings(){
String a = "Hello";
String b = "Johnny";
String c = "Dew";

String result = a + b + c;
}

Jasmin

.method public concatStrings()V
.limit stack 3
.limit locals 5
.var 0 is this Lcom/crack/java/StringConcat; from Label0 to Label1
.var 1 is a Ljava/lang/String; from Label2 to Label1
.var 2 is b Ljava/lang/String; from Label4 to Label1
.var 3 is c Ljava/lang/String; from Label6 to Label1
.var 4 is result Ljava/lang/String; from Label1 to Label1

Label0:
ldc "Hello"
astore_1
Label2:
ldc "Johnny"
astore_2
Label4:
ldc "Dew"
astore_3
Label6:
new java/lang/StringBuilder
dup
aload_1
invokestatic java/lang/String/valueOf(Ljava/lang/Object;)Ljava/lang/String;
invokespecial java/lang/StringBuilder/<init>(Ljava/lang/String;)V
aload_2
invokevirtual java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;
aload_3
invokevirtual java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;
invokevirtual java/lang/StringBuilder/toString()Ljava/lang/String;
astore 4
Label1:
return

.end method

When concatenate String using '+' sign in one statement, Java compiler will translate it to 
a StringBuilder operations.

·         Concatenate Strings using shortcut assignment operator (+=).

Java code

public void concatStrings(){
String a = "Hello";
String b = "Johnny";
String c = "Dew";

String result = null;
result += a;
result += b;
result += c;

}

Jasmin

.method public concatStrings()V
.limit stack 3
.limit locals 5
.var 0 is this Lcom/crack/java/StringConcatShortcutAssignmentOperator; from Label0 to Label1
.var 1 is a Ljava/lang/String; from Label2 to Label1
.var 2 is b Ljava/lang/String; from Label4 to Label1
.var 3 is c Ljava/lang/String; from Label6 to Label1
.var 4 is result Ljava/lang/String; from Label8 to Label1

Label0:
ldc "Hello"
astore_1
Label2:
ldc "Johnny"
astore_2
Label4:
ldc "Dew"
astore_3
Label6:
aconst_null
astore 4
Label8:
new java/lang/StringBuilder
dup
aload 4
invokestatic java/lang/String/valueOf(Ljava/lang/Object;)Ljava/lang/String;
invokespecial java/lang/StringBuilder/<init>(Ljava/lang/String;)V
aload_1
invokevirtual java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;
invokevirtual java/lang/StringBuilder/toString()Ljava/lang/String;
astore 4

new java/lang/StringBuilder
dup
aload 4
invokestatic java/lang/String/valueOf(Ljava/lang/Object;)Ljava/lang/String;
invokespecial java/lang/StringBuilder/<init>(Ljava/lang/String;)V
aload_2
invokevirtual java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;
invokevirtual java/lang/StringBuilder/toString()Ljava/lang/String;
astore 4

new java/lang/StringBuilder
dup
aload 4
invokestatic java/lang/String/valueOf(Ljava/lang/Object;)Ljava/lang/String;
invokespecial java/lang/StringBuilder/<init>(Ljava/lang/String;)V
aload_3
invokevirtual java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;
invokevirtual java/lang/StringBuilder/toString()Ljava/lang/String;
astore 4
Label1:
return

.end method

When concatenate Strings using "+=" sign, the one "+=" called, the one StringBuilder will be created.

·         Concatenate Strings using StringBuilder.

Java code

public void concatStrings(){
String a = "Hello";
String b = "Johnny";
String c = "Dew";

StringBuilder builder = new StringBuilder(a);
builder.append(b);
builder.append(c);

String result = builder.toString();
}

Jasmin

.method public concatStrings()V
.limit stack 3
.limit locals 6
.var 0 is this Lcom/crack/java/StringConcatStringBuilder; from Label0 to Label1
.var 1 is a Ljava/lang/String; from Label2 to Label1
.var 2 is b Ljava/lang/String; from Label4 to Label1
.var 3 is c Ljava/lang/String; from Label6 to Label1
.var 4 is builder Ljava/lang/StringBuilder; from Label8 to Label1
.var 5 is result Ljava/lang/String; from Label1 to Label1

Label0:
ldc "Hello"
astore_1
Label2:
ldc "Johnny"
astore_2
Label4:
ldc "Dew"
astore_3
Label6:
new java/lang/StringBuilder
dup
aload_1
invokespecial java/lang/StringBuilder/<init>(Ljava/lang/String;)V
astore 4
Label8:
aload 4
aload_2
invokevirtual java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;
pop
aload 4
aload_3
invokevirtual java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;
pop
aload 4
invokevirtual java/lang/StringBuilder/toString()Ljava/lang/String;
astore 5
Label1:
return

.end method

Using StringBuilder is a straightforward way, what are we doing in the Java code will be mostly reflected the operations in the JVM level.


  This blog post is just a result from my curiousness, I just need to know what will be happened in the JVM level when concatenate the Strings in various ways. About the performance of each approach, the results are explicitly answer to this question. So, these are your choices.

No comments:

Post a Comment