May be I am splitting hair, but I was wondering in the following case:
String newString = a + b + c; //case 1
String newString = a.concat(b).concat(c);
On performance Analysis with JDK 1.8, I found case 2 as the winner in terms of performance.
class Solution {
public static void main(String[] args) {
String s ="ABC", s1 = "", s2 = "", s3 = "";
long t1 = System.nanoTime();
for(int i = 1; i < 11; i++) {
s1 = s1 + s;
}
System.out.println(System.nanoTime() - t1);
System.out.println(s1);
long t2 = System.nanoTime();
for(int i = 1; i < 11; i++) {
s2 = s2.concat(s);
}
System.out.println(System.nanoTime() - t2);
System.out.println(s2);
long t3 = System.nanoTime();
StringBuilder sb = new StringBuilder();
for(int i = 1; i < 11; i++) {
sb.append(s);
}
s3 = sb.toString();
System.out.println(System.nanoTime() - t3);
System.out.println(s3);
}
}
Results :
40615
ABCABCABCABCABCABCABCABCABCABC
9157
ABCABCABCABCABCABCABCABCABCABC
20243
ABCABCABCABCABCABCABCABCABCABC
Case 1 is concise, expresses the intent clearly, and is equivalent to case 3.
Case 2 is less efficient, and also less readable.
Case 3 is nearly as efficient as case 1, but longer, and less readable.
Using case 3 is only better to use when you have to concatenate in a loop. Otherwise, the compiler compiles case 1 to case 3 (except it constructs the StringBuilder with new StringBuilder(a)
), which makes it even more efficient than your case 3).
Case 3 is better in most aspects. In case 3, you don't endup creating 3 string objects. Because of string immutability, 2 will have overhead of creating string object for each + (or) concat.
EDIT: Re-read the document and agree with most of comments, case 1 is case3.
As an addition to the aforementioned, there was a significant performance improvement done under JEP 280 for string concatenation only.
Pls refer to https://openjdk.java.net/jeps/280 and explanation https://dzone.com/articles/jdk-9jep-280-string-concatenations-will-never-be-t
In short, it means that from Java 9 "Hello " + "world"
string concatenation is a preferred way even taking performance into account.
Case 3 is the most performance form, but the JVM converts case 1 to case 3.
But I believe case 2 is the worst, it is not as readable as case 1 and not as perform as case 3.
If you want to concat string in a loop just use case 3, you can test the performance gain easily, but if it is not in a loop (or you are not appending lots of strings in a sequence) they are almost the same.
The cases which you shall not use the + operator are:
String a = "";
for (String x : theStrings) {
a += x;
}
or
String a = b + c;
a = a + d;
a = a + e;
a = a + f;
For simple cases, using +
is clearly more readable.
For rare more complicated cases, StringBuilder
makes sense. If you are splitting across lines, then +
can quickly be a performance drag. Loops go from O(n) performance to O(n^2) - not a problem if n is small, but a big problem if n can be large in awkward circumstances (perhaps when doing something critical, or when someone is being malicious).
Contrary to the other answers, if you've only got three strings, concat
may be the performance winner. Am I mental? No. Consider the other two options. You are creating a StringBuilder
object, with an array. Appending the strings may well require the array to be replaced and you may have odd bits left at the end of the array (thefre's a certain granularity to allocation, so a few extra char
s may or may not increase memory usage). You can compute the necessary capacity if you hate everyone that reads your code. Best case, two arrays (one for StringBuilder
, one for the String
(no sharing for the last eight years)) each of the size of the result text and two other objects (StringBuilder
and String
). Now for the concat
you are going to allocate to String
objects with two arrays, but the first array will be c.length()
shorter. It's a win! Well, not for readability.
Disclaimer: JVM may do wild optimisation, including stack allocation after escape analysis and special casing of core classes. They are more likely to optimise common and simple code than hand-obfuscated code.