It is often argued that avoiding creating objects (especially in loops) is considered good practice.
Then, what is most efficient regarding StringBuffer
?
StringBuffer sb = new StringBuffer();
ObjectInputStream ois = ...;
for (int i=0;i<1000;i++) {
for (j=0;i<10;j++) {
sb.append(ois.readUTF());
}
...
// Which option is the most efficient?
sb = new StringBuffer(); // new StringBuffer instance?
sb.delete(0,sb.length()); // or deleting content?
}
I mean, one could argue that creating an object is faster then looping through an array.
First StringBuffer
is thread-safe which will have bad performance compared to StringBuilder
. StringBuilder is not thread safe but as a result is faster. Finally, I prefer just setting the length to 0 using setLength.
sb.setLength(0)
This is similar to .delete(...)
except you don't really care about the length. Also probably a little faster since it doesn't need to 'delete' anything. Creating a new StringBuilder
(or StringBuffer) would be less efficient. Any time you see new
Java is creating a new object and placing that on the heap.
Note: After looking at the implementation of .delete
and .setLength
, .delete
sets length = 0, and .setLength
sets every thing to '\0'
So you may get a little win with .delete
Just to amplify the previous comments:
From looking at source, delete
() always calls System.arraycopy
(), but if the arguments are (0,count), it will call arraycopy
() with a length of zero, which will presumably have no effect. IMHO, this should be optimized out since I bet it's the most common case, but no matter.
With setLength
(), on the other hand, the call will increase the StringBuilder's capacity if necessary via a call to ensureCapacityInternal
() (another very common case that should have been optimized out IMHO) and then truncates the length as delete
() would have done.
Ultimately, both methods just wind up setting count
to zero.
Neither call does any iterating in this case. Both make an unnecessary function call. However ensureCapacityInternal() is a very simple private method, which invites the compiler to optimize it nearly out of existence so it's likely that setLength
() is slightly more efficient.
I'm extremely skeptical that creating a new instance of StringBuilder could ever be as efficient as simply setting count
to zero, but I suppose that the compiler might recognize the pattern involved and convert the repeated instantiations into repeated calls to setLength
(0). But at the very best, it would be a wash. And you're depending on the compiler to recognize the case.
Executive summary: setLength(0) is the most efficient. For maximum efficiency, pre-allocate the buffer space in StringBuilder when you create it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With