Everytime I had to convert an int
into a String
I picked either ""+a
or Integer.toString(a)
. Now I wondered which way is faster, so I wrote a simple benchmark that calls function_1, function_2 and function_3 10000000 times and prints how long it takes to process the functions. Here are the functions:
public static String i="";
public static String j="";
public static String k="";
public static void function_1()
{
i=Integer.toString(getOne());
}
public static void function_2()
{
j=""+1;
}
public static void function_3()
{
j=""+getOne();
}
public static int getOne()
{
return 1;
}
the output is:
Benchmarking starting...
Executing function_1 10000000 time(s)...
Done executing function_1 in 476 ms.
Executing function_2 10000000 time(s)...
Done executing function_2 in 8 ms.
Executing function_3 10000000 time(s)...
Done executing function_3 in 634 ms.
Benchmarking complete!
I think function_2 is so fast, because it is compiled as
public static void function_2()
{
j="1";
}
so to avoid that, I used the function getOne()
instead. But here is the interesting part(for me): function_3
must be compiled without using the original toString
method of Object
(in this case Integer.toString(1)
because int
is primitive). My question is: How does the compiler actually threat ""+1
so it is slower then calling Integer.toString(1)
?
""
and 1
are known at compile time. This is why in function_2
"" + 1
is really replaced by "1"
while convertion to bytecode.
getOne()
result is unknown at the compilation time so the concatenation will be done in runtime. BUT because concatenation (+) is not efficient it is likely that compiler will change this to StringBuilder.append()
based implementation.
Don't believe me? Try: javap -c ClassName.class
and you will see something like this:
public static void function_2();
Code:
0: ldc #39 // String 1
2: putstatic #16 // Field j:Ljava/lang/String;
5: return
public static void function_3();
Code:
0: new #42 // class java/lang/StringBuilder
3: dup
4: invokespecial #44 // Method java/lang/StringBuilder."<init>":()V
7: invokestatic #28 // Method getOne:()I
10: invokevirtual #45 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
13: invokevirtual #49 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
16: putstatic #16 // Field j:Ljava/lang/String;
19: return
function_2()
have only one String "1", while function_3 have all these method calls with additional StringBuilder inside :)
Keep in mind that some optimization may occur at runtime, but this behavior is JVM and it's configuration dependent.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With