String vs StringBuilder! - top of Musings page

By: Nicholas Duchon.
Date: Aug 20, 2018


Many presentations have suggested that when concatenating many String objects, StringBuilder is more efficient, so I decided to try to find out just what the differences among various approaches really are.


These are my results on my iMac using the parameters:
As you can see:

Table data = output:

    number              Plus ns             Build ns              Char ns
       500           45,288,972              149,523            1,607,211
      1000           59,902,915              146,094            1,983,651
      1500          154,508,901              467,926            1,087,409
      2000          313,943,292              493,729            1,042,908
      2500          309,990,136              924,623              760,421
      3000          435,333,748              358,273              265,833
      3500          731,918,455              352,838              291,833
      4000          472,027,412              415,499              330,397
      4500          603,437,663              538,292              384,516
      5000          741,941,303              526,332              439,440
      5500          904,946,076              648,917              557,638
      6000        1,087,404,315              704,373              525,105
      6500        1,286,219,802              702,047            1,303,877
      7000        1,507,183,980              815,784              631,819
      7500        1,691,152,729              752,773              747,234
      8000        1,946,127,465              924,957              795,926

Code:

// File: StringTests.java
// Date: Aug 30, 2018
// Author: Nicholas Duchon
// Purpose: some String tests
//   > prepare random strings
//   > compare String += vs StringBuilder

import java.util.Random;
import java.util.Scanner;

class StringTests {
   static Random rn = new Random ();
  
   public static void main (String [] args) {
      int countMin, countMax, countStep, stringMin, stringMax;
  
      System.out.print ("Enter countMin, countMax, countStep, stringMin, stringMax: ");
      Scanner sc = new Scanner (System.in);
      countMin  = sc.nextInt ();
      countMax  = sc.nextInt ();
      countStep = sc.nextInt ();
      stringMin = sc.nextInt ();
      stringMax = sc.nextInt ();
  
      System.out.printf ("%10s %20s %20s %20s\n", "number", "Plus ns", "Build ns", "Char ns");
  
      for (int cnt = countMin; cnt < countMax; cnt += countStep) {
         String arr [] = lots (cnt, stringMin, stringMax);
         long x = buildPlus  (arr);
         long y = buildBuild (arr);
         long z = buildChar  (arr);
         System.out.printf ("%10d %,20d %,20d %,20d\n", cnt, x, y, z);
      } // end tests
  
  
} // end main
  
   static long buildPlus (String [] sa) {
      long start, end;
      start = System.nanoTime();
      String st = "";
      for (String s: sa) st += s;
      end  = System.nanoTime ();
      return end - start;
  
} // end method buildPlus
  
   static long buildBuild (String [] sa) {
      long start, end;
      start = System.nanoTime();
      String st = "";
      StringBuilder sb = new StringBuilder ();
      for (String s: sa) sb.append (s);
      end  = System.nanoTime ();
      st = sb.toString ();
      return end - start;
  
} // end method buildBuild
  
   static long buildChar (String [] sa) {
      long start, end;
      start = System.nanoTime();
      int cnt = 0;
      for (String s: sa) cnt += s.length();
      char [] carr = new char [cnt];
     
      for (int i =0, k = 0; i < sa.length; k += sa [i].length(), i++) {
         char [] cs = sa[i].toCharArray();
         for (int j = 0; j < sa[i].length(); j++)
            carr [k] = cs [j];
      }
      String st = new String (carr);
      end  = System.nanoTime ();
      return end - start;
  
} // end method buildChar
  
   // creates lots of random strings
   static String [] lots (int k, int min, int max) {
      String [] sts = new String [k];
      for (int i = 0; i < sts.length; i++)
         sts [i] = rst (rn.nextInt (max - min) + min);
      return sts;
  
} // end method lots
  
   // create a random String of n characters
   static String rst (int n) {
      char [] ca = new char [n];
      // use int +, THEN convert to char
      // otherwise get a conversion error
      for (int i = 0; i < n; i++)
         ca[i] = (char)('a' + rn.nextInt (26));
      String st = new String (ca);
      return st;
   } // end method rst
} // end class StringTests


Nick.