Tuesday, January 8, 2013

Time taken by various string concatenation methods

As the title goes, the objective of the folowing program will be to find out the time difference or performance various string concatenation methods:

i) + operator
ii) String class' concat() method
iii) StringBuffer class' append() method
iv) StringBuilder class' append() method

The program is followed by results in nanoseconds.
Before recording the results, I have warmed up the JVM by running the code multiple times (~10). Part 2 will follow soon, the link will be provided at the end of this article whenever posted.

Assumtions made by us (precisely, what we knew!):

1. + operator takes a lot of time, as each String will be converted to StringBuilder object and other concatenated strings will be appended and at the last, toString() method will be called on that StringBuilder object. For example,
String str = "1";
str = str + "2" + "3";
will result in
StringBuilder message = new StringBuilder();
message.append("1");
message.append("2");
message.append("3");
String str = message.toString();

2. concat() method does nothing special, just concatenates.

3. Each manipulation through above two processes require a new String object to be created.

4. StringBuffer is synchronized, so each time, lock will be acquired on the operated object, and then released.

5. StringBuilder is most preferable, as it is not synchronized and will save on creating a lot of objects.

package in.blogspot.javabambino.string;

/**
 * This class returns the time duration for a process in nanosecs.
 * @author xploreraj
 *
 */
class TimeUtil {
 private long startTime;
 TimeUtil(){
  startTime = System.nanoTime();
 }
 
 public long getElapsedTimeNanos(){
  return System.nanoTime() - startTime;
 }
}

/**
 * This class measures the performance of various string
 * concatenation operations.
 * @author xploreraj
 *
 */
public class ConcatStringPerf {
 private static int iterationCount = 5;
 public static void main(String[] args) {

  // using + operator
  String str = "1";
  TimeUtil timeUtil = new TimeUtil();
  for(int i=1; i<=iterationCount; i++){
   str = str + "*";
  }
  System.out.println(timeUtil.getElapsedTimeNanos() + 
    " ns taken over " + iterationCount + 
    " iterations using +");

  //using + operator again but without loop

  TimeUtil timeUtil1 = new TimeUtil();
  String strr = "6" + ")" + ")" + ")" + ")" + ")";
  System.out.println(timeUtil1.getElapsedTimeNanos() + 
    " ns when +ed manually 5 times without loop");

  // using String class' concat() method

  String str2 = "2";
  TimeUtil timeUtil2 = new TimeUtil();
  for(int i=1; i<=iterationCount; i++){
   str2 = str2.concat("$");
  }
  System.out.println(timeUtil2.getElapsedTimeNanos() + 
    " ns taken over " + iterationCount + 
    " iterations using String concat");

  // using StringBuffer class' append() method

  StringBuffer buffer = new StringBuffer("3");
  TimeUtil timeUtil3 = new TimeUtil();
  for(int i=1; i<=iterationCount; i++){
   buffer = buffer.append("#");
  }
  System.out.println(timeUtil3.getElapsedTimeNanos() + 
    " ns taken over " + iterationCount + 
    " iterations using StringBuffer append");

  // using StringBuilder class' append() method
 
  StringBuilder builder = new StringBuilder("2");
  TimeUtil timeUtil4 = new TimeUtil();
  for(int i=1; i<=iterationCount; i++){
   builder = builder.append("&");
  }
  System.out.println(timeUtil4.getElapsedTimeNanos() + 
    " ns taken over " + iterationCount + 
    " iterations using StringBuilder append");
 }
}

Results: Who won?

i) Machine specs: Win 7, 32 bit, intel Core2Duo, 2.2GHz, 3GB RAM
   JVM: JDK 1.6.0_18

Result
Run 1
Run 2
Run 3
Run 4
Run 5
Run 6
ns taken over 5 iterations using +
72325
68592
76524
76524
76524
75125
ns when +ed manually 5 times without loop
4200
4200
5133
5133
4200
8399
ns taken over 5 iterations using String concat
27997
31730
202043
27064
29397
30330
ns taken over 5 iterations using StringBuffer append
8865
9332
9332
11199
10732
9333
ns taken over 5 iterations using StringBuilder append
631327
642059
861367
1225325
1229991
1973305

ii) Machine specs: Win XP, 32 bit, intel Core i5, 3.2 GHz, 4GB RAM
    JVM: JDK 1.6.0_20 

Result
Run 1
Run 2
Run 3
Run 4
Run 5
Run 6
ns taken over 5 iterations using +
39441
38842
38466
43310
39190
38588
ns when +ed manually 5 times without loop
10002
4249
7808
14164
4294
4770
ns taken over 5 iterations using String concat
15837
35596
32029
19999
47936
28200
ns taken over 5 iterations using StringBuffer append
10435
10657
10803
7190
7491
14412
ns taken over 5 iterations using StringBuilder append
14106
66758
14062
6805
14338
12147

iii) Machine Specs: Win XP, 32 bit, intel Core i5, 3.2 GHz, 4GB RAM;  with -server switch on [java -server ConcatStringPerf ]
     JVM: JDK 1.6.0_20 

Result
Run 1
Run 2
Run 3
Run 4
Run 5
Run 6
ns taken over 5 iterations using +
34487
34445
34431
48864
34424
35019
ns when +ed manually 5 times without loop
10650
2765
2957
3375
2992
4475
ns taken over 5 iterations using String concat
12839
22008
59841
23023
78406
26371
ns taken over 5 iterations using StringBuffer append
16288
15982
15446
12670
10999
16678
ns taken over 5 iterations using StringBuilder append
13660
4197
4255
3761
3827
14737


Please do post anything relevant and researched, and all important points will be compiled in Part 2 of this article. For the time-being, you can read an abstract article on string concatenation here.

No comments:

Post a Comment

Liked or hated the post? Leave your words of wisdom! Thank you :)