
目次
- この記事の目的
- 文字列連結の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以上かかる場合もあるからです。
そこまでパフォーマンスにこだわらない場合は、プロジェクトメンバーの技術力や可読性と相談です。