It’s common knowledge in Java that you want to clear a StringBuilder
object, and not recreate it. Why? GC for instance. But, surprisingly enough, there is no clear()
method on the StringBuilder
class, and so we resort to manual clear methods. The ones I’ve seen are:
new StringBuilder
which basically recreates the objectsetLength(0)
which changes the internal flags of theStringBuilder
delete(0,sb.length())
which deletes the whole buffer
One would think that the best technique is setLength – but I’ve decided to give it a short test.
Here is the code I’ve used:
package com.tona; import java.util.Random; public class TestStringBuffer { private static final int NUM_OF_RUNS = 100000; private static final int MAX_LENGTH = 1000; private static Random rand = new Random(); private static int fillString(StringBuilder sb,boolean isSameLenString) { int length; if (isSameLenString) length = MAX_LENGTH; else length = rand.nextInt(MAX_LENGTH); for (int i = 0; i < length; ++i) sb.append("a"); return length; } private void runBenchmark(boolean isSameLenString) { StringBuilder sb = new StringBuilder(); long start = System.currentTimeMillis(); for (int i = 0; i < NUM_OF_RUNS; ++i) { fillString(sb,isSameLenString); sb.setLength(0); } long end = System.currentTimeMillis(); long diffWithLen0 = end - start; start = System.currentTimeMillis(); for (int i = 0; i < NUM_OF_RUNS; ++i) { fillString(sb,isSameLenString); sb = new StringBuilder(); } end = System.currentTimeMillis(); long diffWithNew = end - start; start = System.currentTimeMillis(); for (int i = 0; i < NUM_OF_RUNS; ++i) { fillString(sb,isSameLenString); sb = new StringBuilder(MAX_LENGTH); } end = System.currentTimeMillis(); long diffWithNewConstLength = end - start; start = System.currentTimeMillis(); for (int i = 0; i < NUM_OF_RUNS; ++i) { fillString(sb,isSameLenString); sb.delete(0, sb.length()); } end = System.currentTimeMillis(); long diffWithDelete = end - start; start = System.currentTimeMillis(); for (int i = 0; i < NUM_OF_RUNS; ++i) { int length = fillString(sb,isSameLenString); sb.delete(0, length); } end = System.currentTimeMillis(); long diffWithDeleteConstLength = end - start; System.out.println("With setLength(0) " + diffWithLen0); System.out.println("With new StringBuilder() " + diffWithNew); System.out.println("With new StringBuilder(MAX_LENGTH) " + diffWithNewConstLength); System.out.println("With delete(0, sb.length()) " + diffWithDelete); System.out.println("With delete(0, length) " + diffWithDeleteConstLength); } public static void main(String[] args) { TestStringBuffer test = new TestStringBuffer(); System.out.println("Constant length string"); test.runBenchmark(true); System.out.println("Changing length string"); test.runBenchmark(false); } }
And here are the results:
Constant length string
With setLength(0) 1524
With new StringBuilder() 1501
With new StringBuilder(MAX_LENGTH) 1365
With delete(0, sb.length()) 1369
With delete(0, length) 1391
Changing length string
With setLength(0) 686
With new StringBuilder() 743
With new StringBuilder(MAX_LENGTH) 796
With delete(0, sb.length()) 715
With delete(0, length) 698
(Note that changing string length uses a Random, so results may vary).
With StringBuilder
object with a fixed length, the new StringBuilder
with the predefined length is the best option, although not much slower than the delete
method. With the varying length strings, setLength
and delete
and more of less on par (give it a few runs and you’ll see it for yourself).
So, now you know how to clean your StringBuilder
object. Enjoy.