目次
- この記事の目的
- 文字列連結の2種類の仕方
- パフォーマンスを比較する
- 10万回ではなく1000回であれば
- 結論
1. この記事の目的
Javaで文字列を連結する際は、String
とStringBuilder
のどちらを使えばいいのかを考えたいと思います。
String
と StringBuilder
の2つのクラスについては色々な主張を見かけます。例えば、
「文字列の連結を何回も行う時は String
ではなく StringBuilder
を使え」
「Java9からは最適化の方法が変わったからString
使っていい」
などです。実際どっちが速いのか実験してみました。
サンプルコードをGitHubにあげました。
Dockerがある環境で python execute_multi.py
で実行してください。
2. 文字列連結の2種類の仕方
String
とStringBuilder
の文字列の連結の方法を紹介します。
まずは String
から、こちらはおなじみかと思います。
public class StringConcatWithOperator { public static void main (String[] args) { long startTime = System.currentTimeMillis(); String message = ""; for (int i = 0; i < 100 * 1000; i++) { message += "a"; } long endTime = System.currentTimeMillis(); System.out.println(" " + (endTime - startTime) + "ms"); } }
String
の +
演算子で文字列を連結しています。
この時、毎回 String
のオブジェクトを作成しては捨てています。
このオブジェクトの作成にコストがかかるので遅くなります。
続いて StringBuilder
です。
public class StringConcatWithBuilder { public static void main (String[] args) { long startTime = System.currentTimeMillis(); StringBuilder builder = new StringBuilder(); for (int i = 0; i < 100 * 1000; i++) { builder.append("a"); } String message = builder.toString(); long endTime = System.currentTimeMillis(); System.out.println(" " + (endTime - startTime) + "ms"); } }
StringBuilder
の append
で文字列を連結しています。
この時は "a"
のオブジェクトも使い回しですし、 StringBuilder
のインスタンスも1つだけです。
さて、パフォーマンスの差はどのようになるのでしょうか。
3. パフォーマンスを比較する
実際に文字列を10万回連結した際の速度をJava8とJava9で比較しました。
バージョン | String | StringBuilder |
---|---|---|
Java8 | 10263ms | 9ms |
Java9 | 1862ms | 13ms |
ここから分かったことを2つまとまます。
String
よりStringBuilder
の方が圧倒的に速いString
の連結の最適化がJava8から9でかなり良くなっている
まず StringBuilder
の方が速い件は、先述のオブジェクトの使い回しが原因です。
String
の連結の最適化については、他の記事によいものがありますので探してみてください。
4. 10万回ではなく1000回であれば
先ほどの実験では10万回文字列を連結しましたが、正直少し現実的ではありません。
そこで、1000回ぐらいだと String
の方が速いんじゃないの?ということでこちらも実験します。
結果は以下の通りです。
バージョン | String | StringBuilder |
---|---|---|
Java8 | 5ms | 1ms |
Java9 | 121ms | 1ms |
ここから分かったことを2つまとまます。
- 相変わらず
StringBuilder
の方がはやいが、Java8ではほぼ差はない String
の連結はJava9よりJava8の方がはやい
Java9の最適化はDynamicInvokeという方法らしいのですが、文字列の数が多くなるほど効くようです。
5. 結論
結論は、「場合による」。
まず、数万以上の文字列を連結を行う場合は StringBuilder
を使うべきです。
100分の1程度の時間で文字列の連結を行えるからです。
千程度の文字列を連結する際も、 StringBuilder
の方が速いは速いです。
アプリやゲームなどで、1フレームで使える時間が限られている場合は StringBuilder
がいいです。
Java9だと100ms以上かかる場合もあるからです。
そこまでパフォーマンスにこだわらない場合は、プロジェクトメンバーの技術力や可読性と相談です。