In this article, we will discuss difference between String, StringBuffer and StringBuilder in detail with example on performance
Let us move forward and discuss difference between them;
1. String v/s StringBuffer v/s StringBuilder:
String | StringBuffer |
StringBuilder |
String is immutable | StringBuffer is mutable and synchronized | StringBuilder is also mutable but it is non-synchronized |
Since String is immutable, therefore it is synchronized which means it is thread-safe | In StringBuffer, 2 or more threads aren’t allowed to operate on same StringBuffer object simultaneously | Whereas StringBuilder allows multiple threads to be operated on the same StringBuilder object |
String is safe to be used in a multi-threaded environment | In simple word, it is thread-safe while working in a multi-threaded environment | It is not thread-safe while working in a multi-threaded environment |
All string literals are stored inside String Constant Pool (SCP)
whereas String objects are stored inside heap memory | StringBuffer objects are stored inside Java heap memory | StringBuffer objects are stored inside Java heap memory |
Performing concatenation operation on String results in poor performance
Because of overhead in creating new String literal every-time Note: old literal still be placed inside String Constant pool (SCP) | Due to synchronization, performance gets a big hit;
because every thread has to acquire and release lock before any operations on StringBuffer object | Due to non-synchronization, performance is relatively faster than StringBuffer;
As no thread has to wait to acquire and release lock which is overhead in case of StringBuffer |
Q) When to use String, StringBuffer and StringBuilder ?
String:
- When there are not many modification on same string and it is going to remain constant over a period of time, then String is preferred
- In addition, when using string provides thread-safety
StringBuffer:
- In a multi-threaded application, StringBuffer need to be preferred as it ensure thread-safety
- Though it will be slower when compared with StringBuilder but ensures data-consistency by not allowing multiple threads to operate at the same time concurrently
- Because every time lock has to be acquired before any operation on StringBuffer object and only after releasing the lock, 2nd thread can take charge
StringBuilder:
- In a single threaded application, StringBuilder is a very apt choice as it is doesn’t require thread-safety
- And also it will get rid of acquiring and releasing lock and hence performance will be improved effectively when comparing with StringBuffer
2. Example on performance of String, StringBuilder v/s StringBuffer:
StringVsStringBufferVsStringBuilderPerformanceTest.java
package in.bench.resources.performance.test;
public class StringVsStringBufferVsStringBuilderPerformanceTest {
public static void main(String[] args) {
// counter
int iCount = 0;
long startTime = 0;
long endTime = 0;
// sample String
String testStr = "";
// START time for String concatenation
startTime = System.currentTimeMillis();
// Test 1: for String concatenation
while(iCount < 15000) {
testStr = testStr + "BenchResources.Net";
// increment counter by 1
iCount++;
}
// END time for String concatenation
endTime = System.currentTimeMillis();
System.out.println("The time taken for "
+ "String concatenation is : "
+ (endTime - startTime) + "ms");
// sample StringBuffer
StringBuffer buffer = new StringBuffer();
// START time for StringBuffer append() operation
startTime = System.currentTimeMillis();
// assign ZERO to counter
iCount = 0;
// Test 2: for StringBuffer append() operation
while(iCount < 15000) {
buffer.append("BenchResources.Net");
// increment counter by 1
iCount++;
}
// END time for StringBuffer append() operation
endTime = System.currentTimeMillis();
System.out.println("The time taken for "
+ "StringBuffer append() is : "
+ (endTime - startTime) + "ms");
// sample StringBuilder
StringBuilder builder = new StringBuilder();
// START time for String concatenation
startTime = System.currentTimeMillis();
// assign ZERO to counter
iCount = 0;
// Test 2: for StringBuilder append() operation
while(iCount < 15000) {
builder.append("BenchResources.Net");
// increment counter by 1
iCount++;
}
// END time for String concatenation
endTime = System.currentTimeMillis();
System.out.println("The time taken for "
+ "StringBuilder append() is : "
+ (endTime - startTime) + "ms");
}
}
Output:
The time taken for String concatenation is : 5902ms
The time taken for StringBuffer append() is : 2ms
The time taken for StringBuilder append() is : 1ms
Note:
- There will be slight difference in the result on executing at various times
- Out of 3, String concatenation will yield poor result as it has to create new string-literal every-time inside String Constant Pool (SCP)
- StringBuilder will be faster than StringBuffer, as it is non-synchronized
Hope, you found this article very helpful. If you have any suggestion or want to contribute any other way or tricky situation you faced during Interview hours, then share with us. We will include that code here.
Related Articles:
- String v/s StringBuffer
- StringBuffer v/s StringBuilder
- String v/s StringBuffer v/s StringBuilder
- How to clear or delete StringBuffer contents
- How to append new line to StringBuffer
- Difference between capacity() and length() methods of StringBuffer
- Convert first character of every word to uppercase
References:
- https://docs.oracle.com/javase/tutorial/essential/concurrency/immutable.html
- https://docs.oracle.com/javase/tutorial/essential/concurrency/imstrat.html
- https://docs.oracle.com/javase/tutorial/java/data/strings.html
- https://docs.oracle.com/javase/8/docs/api/java/lang/String.html
- https://docs.oracle.com/javase/8/docs/api/java/lang/class-use/String.html
- https://docs.oracle.com/javase/8/docs/api/java/lang/StringBuffer.html
- https://docs.oracle.com/javase/8/docs/api/java/lang/StringBuilder.html
Happy Coding !!
Happy Learning !!