Pages

Sunday, October 7, 2012

Performance of string comparison in Java

Have you ever wonder how fast Java can compare two strings? Which method is the best? The answer is.... it depends what you are compare. Let's do some tests. We will try to compare the intern strings and dynamic created by both '==' and equals methods. Here is the code which do the checking:
String s1 = "test";
String s2 = "test";
String s3 = s1 + "";
String s4 = s3 + "";
String s5 = s4;
long iterations = 100000000;
long time = System.currentTimeMillis();

for (int i = 0; i < iterations; i++) {
    if (s1 == s2);
}
System.out.println("s1==s2: " + (System.currentTimeMillis() - time));

time = System.currentTimeMillis();
for (int i = 0; i < iterations; i++) {
    if (s1 == s3.intern());
}
System.out.println("s1==s3.intern(): " + (System.currentTimeMillis() - time));

for (int i = 0; i < iterations; i++) {
    if (s1.equals(s3.intern()));
}
System.out.println("s1.equals(s3.intern()): " + (System.currentTimeMillis() - time));

time = System.currentTimeMillis();
for (int i = 0; i < iterations; i++) {
    if (s1.equals(s2));
}
System.out.println("s1.equals(s2): " + (System.currentTimeMillis() - time));

time = System.currentTimeMillis();
for (int i = 0; i < iterations; i++) {
    if (s1.equals(s3));
}
System.out.println("s1.equals(s3): " + (System.currentTimeMillis() - time));
time = System.currentTimeMillis();
for (int i = 0; i < iterations; i++) {
    if (s3.equals(s1));
}
System.out.println("s3.equals(s1): " + (System.currentTimeMillis() - time));

time = System.currentTimeMillis();
for (int i = 0; i < iterations; i++) {
    if (s3.equals(s4));
}
System.out.println("s3.equals(s4): " + (System.currentTimeMillis() - time));

time = System.currentTimeMillis();
for (int i = 0; i < iterations; i++) {
    if (s3.intern() == s4.intern());
}
System.out.println("s3.intern()==s4.intern(): " + (System.currentTimeMillis() - time));
time = System.currentTimeMillis();
for (int i = 0; i < iterations; i++) {
    if (s3.intern().equals(s4.intern()));

}
System.out.println("s3.intern().equals(s4.intern()): " + (System.currentTimeMillis() - time));
time = System.currentTimeMillis();
for (int i = 0; i < iterations; i++) {
    if (s5 == s4);
}
System.out.println("s5==s4: " + (System.currentTimeMillis() - time));
}
And the result is:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
s1==s2: 95
s1==s3.intern(): 12925
s1.equals(s3.intern()): 25778
s1.equals(s2): 88
s1.equals(s3): 90
s3.equals(s1): 89
s3.equals(s4): 314
s3.intern()==s4.intern(): 26148
s3.intern().equals(s4.intern()): 26083
s5==s4: 310

So as you can see there is no big difference in comparison strings using reference comparison nd equals method (test 1 and  4 for intern strings, 7 and 10 for dynamically created). What is interesting that comparing two dynamically created string is takes nearly 3.5 times longer than in case when at least of the arguments is intern string. As you can also see using the intern() method is really time consuming. The interesting result is also comparison of the second and third case. Why the time is more than doubled when equals is used?

Now, lets check how the results change when we use the longer string. The same tests but now s1 and s2 strings are 248 characters long.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
s1==s2: 135
s1==s3.intern(): 187042
s1.equals(s3.intern()): 374946
s1.equals(s2): 90
s1.equals(s3): 89
s3.equals(s1): 89
s3.equals(s4): 316
s3.intern()==s4.intern(): 373573
s3.intern().equals(s4.intern()): 374662
s5==s4: 311

The results are quite surprising. The equals() method doesn't depend on the length of its arguments! However the intern() method needs much more time.

0 komentarze:

Post a Comment