
Java String Classes Performance comparison
Ever wondered how actually the performance of Java string classes differs?
In this topic, I tried to compare the performance of the java.lang classes of the String, StringBuilder and StringBuffer classes.
It's no secret that in Java there are three main classes for working with strings. The main class that we use most often in programs is String . A feature of this class is that it creates immutable strings. Those. which character string we initialized when creating the object, it will remain that way. Therefore, the construction: Create a new object containing the string "MashaSasha" and the original objects will be destroyed by the garbage collector. If there are many concatenation operations on the same string object, this leads to an intensive process of generating new objects and adds work to the garbage collector. If we need mutable strings, developers offer us other classes. The first one that was originally in Java was StringBuffer
and a newer StringBuilder (appeared since version 1.5). As the documentation says , StringBuffer is safe to use in multi-threaded applications, but the second is more efficient.
Well, more effective, less effective, this one is certainly good, but I want numbers. After all, another programmer might think, but is it worth using the "inconvenient" StringBuffer / StringBuilder instead of such a wonderful String in order to save a couple of milliseconds? Others will say that there are no such situations when you need to perform, say, one hundred thousand concatenations ... But curiously, is there a big difference?
We read the lines from the text file “onegin.txt” (we will call the classic to help). The file has a size of 297463 bytes, utf-8, 27195 words. Let's put all the words of the file on one line using all three classes and compare performance. To make it more interesting, let's test on different JVMs and two OSs. Linux (I use LinuxMint 9 is such an ornate Ubuntu, if anyone does not know) well, and Win XP Pro SP3. Both OSes are 32-bit, because I am writing from a netbook with Atom N280. But we do not set records, the trend is important to us.
Actually the program itself, nowhere is simpler:
The options for StringBuffer and StringBuilder are similar, and are displayed in the comments.
Measurements of the operating time of each option for each virtual machine were made 5 times and the average value was calculated.
If we need modifiable strings, we use StringBuffer (in multi-threaded applications) and StringBuilder in the rest. The difference is very noticeable.
It is clear why the JVM from the Open JDK is slightly behind, something there Sun or already twisted Oracle. It is not entirely clear why there is such a big difference in working with String class objects under Linux and WinXP. Tolley Win does not allow the JVM to work as efficiently as Linux, or is it a feature of the JVM implementation ... You need to dig further.
For reference:
JRockit is a virtual machine from Oracle.
HotSpot is a machine originally developed by Sun, now bought by itself by Oracle.
Open JDK - Open-source JDK based on the source code at one time open by Sun.
In this topic, I tried to compare the performance of the java.lang classes of the String, StringBuilder and StringBuffer classes.
Obvious facts
It's no secret that in Java there are three main classes for working with strings. The main class that we use most often in programs is String . A feature of this class is that it creates immutable strings. Those. which character string we initialized when creating the object, it will remain that way. Therefore, the construction: Create a new object containing the string "MashaSasha" and the original objects will be destroyed by the garbage collector. If there are many concatenation operations on the same string object, this leads to an intensive process of generating new objects and adds work to the garbage collector. If we need mutable strings, developers offer us other classes. The first one that was originally in Java was StringBuffer
String st = "Маша";
st += "Саша";
and a newer StringBuilder (appeared since version 1.5). As the documentation says , StringBuffer is safe to use in multi-threaded applications, but the second is more efficient.
What do you want
Well, more effective, less effective, this one is certainly good, but I want numbers. After all, another programmer might think, but is it worth using the "inconvenient" StringBuffer / StringBuilder instead of such a wonderful String in order to save a couple of milliseconds? Others will say that there are no such situations when you need to perform, say, one hundred thousand concatenations ... But curiously, is there a big difference?
Test
We read the lines from the text file “onegin.txt” (we will call the classic to help). The file has a size of 297463 bytes, utf-8, 27195 words. Let's put all the words of the file on one line using all three classes and compare performance. To make it more interesting, let's test on different JVMs and two OSs. Linux (I use LinuxMint 9 is such an ornate Ubuntu, if anyone does not know) well, and Win XP Pro SP3. Both OSes are 32-bit, because I am writing from a netbook with Atom N280. But we do not set records, the trend is important to us.
Actually the program itself, nowhere is simpler:
package stringtest1;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws FileNotFoundException, IOException {
BufferedReader reader = new BufferedReader(new FileReader("onegin.txt"));
StringBuilder sb = new StringBuilder();
String line = null;
while ( (line = reader.readLine()) != null) {
sb.append(line).append("\n");
}
reader.close();
String[] words = sb.toString().split("\\s+");
System.out.println("Total words:" + words.length);
waitEnter();
long ts = System.nanoTime();
String buff = "";
//2 StringBuffer buff = new StringBuffer();
//3 StringBuilder buff = new StringBuilder();
for (String word : words) {
buff += word + " ";
//2&3 buff.append(word).append(" ");
}
long te =System.nanoTime();
System.out.println("Complete, lenght:" + buff.length() + " elapsed time:" + (te - ts)/1e6 + "ms");
}
private static void waitEnter() {
Scanner scan = new Scanner(System.in);
System.out.print("Press Enter key.");
scan.nextLine();
}
}
* This source code was highlighted with Source Code Highlighter.
The options for StringBuffer and StringBuilder are similar, and are displayed in the comments.
Measurements of the operating time of each option for each virtual machine were made 5 times and the average value was calculated.
results
Linux
Class | Open JDK 1.6.0_18 | HotSpot 1.6.0_20 | JRockit 4.0.1 |
---|---|---|---|
String | 27390ms | 26850ms | 26940ms |
StringBuffer | 35.55ms | 34.87ms | 15.41ms |
StringBuilder | 33.01ms | 31.78ms | 12.82ms |
Windows XP
Class | HotSpot 1.6.0_20 | JRockit 4.0.1 |
---|---|---|
String | 55260ms | 45330ms |
StringBuffer | 19.38ms | 14.50ms |
StringBuilder | 16.83ms | 12.76ms |
conclusions
If we need modifiable strings, we use StringBuffer (in multi-threaded applications) and StringBuilder in the rest. The difference is very noticeable.
It is clear why the JVM from the Open JDK is slightly behind, something there Sun or already twisted Oracle. It is not entirely clear why there is such a big difference in working with String class objects under Linux and WinXP. Tolley Win does not allow the JVM to work as efficiently as Linux, or is it a feature of the JVM implementation ... You need to dig further.
For reference:
JRockit is a virtual machine from Oracle.
HotSpot is a machine originally developed by Sun, now bought by itself by Oracle.
Open JDK - Open-source JDK based on the source code at one time open by Sun.