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 :)