I often hear that in Java it's faster to use StringBuilder
instead of addition when concatenating strings, but sometimes it's not. Example.
$ 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
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);
}
}
run.rb
%w( UseStringBuilder UseStringPlus ).each do |name|
p name
puts( %x( javac #{name}.java && time java #{name} 10000000 ) )
end
"UseStringBuilder"
real 0m2.594s
user 0m2.488s
sys 0m0.356s
0
"UseStringPlus"
real 0m0.227s
user 0m0.239s
sys 0m0.036s
0
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);
}
}
%w( UseStringBuilder2 UseStringPlus2 ).each do |name|
p name
puts( %x( javac #{name}.java && time java #{name} 10000 a ) )
end
"UseStringBuilder2"
real 0m1.838s
user 0m1.608s
sys 0m0.450s
0
"UseStringPlus2"
real 0m0.917s
user 0m0.903s
sys 0m0.263s
0
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