Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts

Thursday, May 8, 2014

String Concatenation In Java

While working on my project the issue of efficiency while concatenating strings came up. In Java manipulation of Strings is usually done via two classes, the String class & the StringBuilder class. The String class is more popular among developers, since it provides enough functionality to cover most people’s needs and the resulting syntax is intuitive. The StringBuilder class is seldom used compared to the String class because it doesn’t add anything extra that the regular String class already doesn’t cover and it’s syntax is somewhat burdensome. The only time it’s really ever used is when concatenation is being done and efficiency is a critical factor. Why can’t the String class be used exclusively when concatenating strings? Well, it is usually not recommended primarily because Strings in Java are immutable, and concatenation requires the creation of a new String object. This is a relatively inexpensive action and when done infrequently results in minimal overhead. However, when concatenation is done a lot, like in a loop for instance, then it becomes phenomenally expensive and unnecessary.

According to the Java documentation, the StringBuilder class is used to represent a mutable sequence of characters. Concatenation of StringBuilders occurs in place thereby resulting in a significant increase in efficiency and greater time savings. The only area in which the StringBuilder class loses out to its competition is syntax and aesthetics. Use of the StringBuilder class potentially inhibits readability, as the syntax for its use requires the calling of methods (i.e. instead of concatenating strings a & b like this: a + b, it's like this: a.append(b)).

For the longest time I’d been under the impression that it didn’t matter whether or not you used the StringBuilder class because the compiler would transmute the code to the more efficient alternative anyways (smart compiler is smart). This assumption was merely an assumption and had no basis in anything whatsoever. So to settle the issue once and for all I decided to test everything empirically:

This was the code I used:
//String Builder
long x = 0, y = 0;
x = System.nanoTime();
StringBuilder s = new StringBuilder();
for (int i = 0; i < 10000; i++) {
s.append(“x”);
}
y = System.nanoTime();
//String
long x = 0, y = 0;
x = System.nanoTime();
String s = “”;
for (int i = 0; i < 10000; i++) {
s += “x”;
}
y = System.nanoTime();
After running the above code, I got the following times:
StringBuilder: avg time 0.01s.
String: avg time 0.20 seconds.
Evidently, the StringBuilder class is much more efficient (more than ten times so). So while Donald Knuth’s classic aphorism:
We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil.
… should be adhered to at all times, it is probably best to consider using the StringBuilder class exclusively when concatenating strings of any sort. For some more insight into how the compiler deals with strings in different contexts peruse this excellent Stack Overflow thread (http://stackoverflow.com/questions/1532461/stringbuilder-vs-string-concatenation-in-tostring-in-java):