Example of using addition faster than using StringBuilder (Java)

I often hear that in Java it's faster to use StringBuilder instead of addition when concatenating strings, but sometimes it's not. Example.

Execution environment

$ java --version
openjdk 12 2019-03-19
OpenJDK Runtime Environment (build 12+33)
OpenJDK 64-Bit Server VM (build 12+33, mixed mode, sharing)
$ javac --version
javac 12

Sample code 1

UseStringBuilder

UseStringBuilder.java


public class UseStringBuilder {
  private static int receiver(String s) {
    if (s.equals("hoge")) {
      return 1;
    } else {
      return 0;
    }
  }

  private static final String foo = "uprjkdowvyvqxlncsjgqzstikgclvgorshfrruifnnuzcfqtgtojfqsakcfvaisaysaxbrlpfczukomfxoebwypmqbkqmeevgivpdxnawthcazjobhhhydlbeiltwbmvwsykslyudqludjqlmkzilhreuxyajqgpiwebbxdnccrfmictdxolowxxnaeoucmtybdnmujrwshdezptpjpmzjdnasikhjztfnuezvipxwvywhgvmzqtrfehkkbrgganygop";
  private static final String bar = "bjsqdbkweettnvympybihyjrkhqtedvpogounxelthhyrtbpzoldujwzmmspacjtxwjwciusocwimihuumzvarvyqorunyinmqlkaefmlghcoxsvqbbazlbgavsffmqnjyaqturfgvwrfsgdcrksdexcipznpovpzilbgpxewclexahkxylffwsjiuiuthtbkrkqimcfcfzkoptzsroljeagdzgacdpgxdqwnjymwnnvqlohvsyxkbnazgedrxdjukfh";
  private static final String baz = "phblfiycdsnaahcskasevmthowdijgvfxdzuiivsubtqdwqzcbjhxvlhclkxnmpikfphceulcypiukpkrwzrnmzabydgmfwulrkjbonpcfgvjfbewdavycsjaqfsgvuqunblbzysezasrlrkeawotzjmdvemcqfditpjuolntiymrwxbgmhupoznjydqxzhghgifwnbkgosarjtuvxgneqorxzjemqtepwldrmqytkygsfetvnclqhyxoprioatxxkwo";
  private static final String qux = "rysvvsftwtolxonofdvkjjepouyayiyszgehjuqmunagaaiacrlpalcyizpwmrscldwpfiggobbsynzczfjhcqoqmlkvobljithjucwxmyzdsbrhkjpnpezxmqegbllwcdtraovdupkhbnsekkszffesmrpigwaeqqdxtnklusiwyljbhkzhktarxcraqvcvdybpunxeqnurmrbhoptgdffcfwwemqxvivxhgdnyttkivxjfzzhbqgujigmwmetnuxod";
  private static final String quux = "aodwvgukhmcwrzxwpmlucjnnwtjviytbtbahyexaefkmmweozifczxnzxafwbyjgoknssrtrdoihwhxmktsykfgapffmzqujlgtovsikgjwjtzcuxkgmequueqlnjratiqrznxpyomvsyiccbiyqrwbelbhpvvpgscqzpdsnqrohphdiomjcwivxddpyqelcdnapzlixbqdsfrehamzhyaavpuxjklllvulfqyostchdrgjgdbugfoeuknbsbrntkevf";

  public static void main(String[] args) {
    int sum = 0;
    String[] bars = new String[] { "baz", "qux" };
    for (int i = 0; i < Integer.parseInt(args[0]); ++i) {
      sum += receiver(new StringBuilder()
      .append("hoge")
      .append( foo )
      .append( bar )
      .append( baz )
      .append( qux )
      .append( quux )
      .toString() );
    }
    System.out.println(sum);
  }
}

UseStringPlus

UseStringPlus.java


public class UseStringPlus {
  private static int receiver( String s ){
    if ( s.equals("hoge") ){
      return 1;
    } else {
      return 0;
    }
  }
  private static final String foo = "uprjkdowvyvqxlncsjgqzstikgclvgorshfrruifnnuzcfqtgtojfqsakcfvaisaysaxbrlpfczukomfxoebwypmqbkqmeevgivpdxnawthcazjobhhhydlbeiltwbmvwsykslyudqludjqlmkzilhreuxyajqgpiwebbxdnccrfmictdxolowxxnaeoucmtybdnmujrwshdezptpjpmzjdnasikhjztfnuezvipxwvywhgvmzqtrfehkkbrgganygop";
  private static final String bar = "bjsqdbkweettnvympybihyjrkhqtedvpogounxelthhyrtbpzoldujwzmmspacjtxwjwciusocwimihuumzvarvyqorunyinmqlkaefmlghcoxsvqbbazlbgavsffmqnjyaqturfgvwrfsgdcrksdexcipznpovpzilbgpxewclexahkxylffwsjiuiuthtbkrkqimcfcfzkoptzsroljeagdzgacdpgxdqwnjymwnnvqlohvsyxkbnazgedrxdjukfh";
  private static final String baz = "phblfiycdsnaahcskasevmthowdijgvfxdzuiivsubtqdwqzcbjhxvlhclkxnmpikfphceulcypiukpkrwzrnmzabydgmfwulrkjbonpcfgvjfbewdavycsjaqfsgvuqunblbzysezasrlrkeawotzjmdvemcqfditpjuolntiymrwxbgmhupoznjydqxzhghgifwnbkgosarjtuvxgneqorxzjemqtepwldrmqytkygsfetvnclqhyxoprioatxxkwo";
  private static final String qux = "rysvvsftwtolxonofdvkjjepouyayiyszgehjuqmunagaaiacrlpalcyizpwmrscldwpfiggobbsynzczfjhcqoqmlkvobljithjucwxmyzdsbrhkjpnpezxmqegbllwcdtraovdupkhbnsekkszffesmrpigwaeqqdxtnklusiwyljbhkzhktarxcraqvcvdybpunxeqnurmrbhoptgdffcfwwemqxvivxhgdnyttkivxjfzzhbqgujigmwmetnuxod";
  private static final String quux = "aodwvgukhmcwrzxwpmlucjnnwtjviytbtbahyexaefkmmweozifczxnzxafwbyjgoknssrtrdoihwhxmktsykfgapffmzqujlgtovsikgjwjtzcuxkgmequueqlnjratiqrznxpyomvsyiccbiyqrwbelbhpvvpgscqzpdsnqrohphdiomjcwivxddpyqelcdnapzlixbqdsfrehamzhyaavpuxjklllvulfqyostchdrgjgdbugfoeuknbsbrntkevf";
  public static void main( String[] args ){
    int sum=0;
    String[] bars = new String[]{ "baz", "qux" };
    for( int i=0 ; i<Integer.parseInt(args[0]) ; ++i ){
      sum += receiver( 
        "hoge"
        + foo 
        + bar 
        + baz 
        + qux 
        + quux 
       );
    }
    System.out.println(sum);
  }
}

The person who runs

run.rb


%w( UseStringBuilder UseStringPlus ).each do |name|
  p name
  puts( %x( javac #{name}.java && time java #{name} 10000000 ) )
end

Execution result

"UseStringBuilder"

real	0m2.594s
user	0m2.488s
sys	0m0.356s
0
"UseStringPlus"

real	0m0.227s
user	0m0.239s
sys	0m0.036s
0

Sample code 2

Comment, and an experiment with a sample that does not combine at compile time.

UseStringBuilder2

UseStringBuilder2.java


public class UseStringBuilder2 {
  private static int receiver(String s) {
    if (s.equals("hoge")) {
      return 1;
    } else {
      return 0;
    }
  }

  private static String makestr(int len, char c0){
    StringBuilder b = new StringBuilder();
    for( int i=0 ; i<len*1024 ; ++i ){
      b.append(c0+(char)i);
    }
    return b.toString();
  }

  public static void main(String[] args) {
    String foo = makestr(1, args[1].charAt(0));
    String bar = makestr(2, args[1].charAt(0));
    String baz = makestr(4, args[1].charAt(0));
    String qux = makestr(8, args[1].charAt(0));
    String quux = makestr(16, args[1].charAt(0));
    String corge = makestr(32, args[1].charAt(0));
    int sum = 0;
    String[] bars = new String[] { "baz", "qux" };
    for (int i = 0; i < Integer.parseInt(args[0]); ++i) {
      sum += receiver(new StringBuilder()
      .append("hoge")
      .append( foo )
      .append( bar )
      .append( baz )
      .append( qux )
      .append( quux )
      .append( corge )
      .toString() );
    }
    System.out.println(sum);
  }
}

UseStringPlus2

UseStringPlus2.java


public class UseStringPlus2 {
  private static int receiver( String s ){
    if ( s.equals("hoge") ){
      return 1;
    } else {
      return 0;
    }
  }
  private static String makestr(int len, char c0){
    StringBuilder b = new StringBuilder();
    for( int i=0 ; i<len*1024 ; ++i ){
      b.append(c0+(char)i);
    }
    return b.toString();
  }
  public static void main( String[] args ){
    String foo = makestr(1, args[1].charAt(0));
    String bar = makestr(2, args[1].charAt(0));
    String baz = makestr(4, args[1].charAt(0));
    String qux = makestr(8, args[1].charAt(0));
    String quux = makestr(16, args[1].charAt(0));
    String corge = makestr(32, args[1].charAt(0));
    int sum=0;
    for( int i=0 ; i<Integer.parseInt(args[0]) ; ++i ){
      sum += receiver( 
        "hoge"
        + foo 
        + bar 
        + baz 
        + qux 
        + quux 
        + corge
       );
    }
    System.out.println(sum);
  }
}

The person who runs

%w( UseStringBuilder2 UseStringPlus2 ).each do |name|
  p name
  puts( %x( javac #{name}.java && time java #{name} 10000 a ) )
end

Execution result

"UseStringBuilder2"

real	0m1.838s
user	0m1.608s
sys	0m0.450s
0
"UseStringPlus2"

real	0m0.917s
user	0m0.903s
sys	0m0.263s
0

so

So, in the above cases, it is faster to connect by addition.

I think there are various things such as reversal depending on the Java version.

Recommended Posts

Example of using addition faster than using StringBuilder (Java)
Example of params using where
Example of using abstract class
[Kotlin] Example of processing using Enum
Summary of object-oriented programming using Java
I tried using GoogleHttpClient of Java
[Java] Write a sort faster than Arrays.sort
Summary of changes other than JEP of Java10
Example of using ArAutoValueConverter (field type conversion)
Verification of performance impact when using Java volatile
[Java] The confusing part of String and StringBuilder
Try similar search of Image Search using Java SDK [Search]
Story of test automation using Appium [Android / java]
[Java] Overview of Java
Implementation example of simple LISP processing system (Java version)
[Java10] Be careful of using var and generics together
[Java] Handling of character strings (String class and StringBuilder class)
Example of using Iterator in Java (Bonus: Super convenient! Compositing Iterator ~ Do something like flatMap to Iterator)