Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fastest way of converting integer to string in java

Everytime I had to convert an intinto a String I picked either ""+aor 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)?

like image 503
D180 Avatar asked Mar 27 '13 20:03

D180


1 Answers

"" 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.

like image 50
msi Avatar answered Oct 21 '22 16:10

msi