こんにちは
引き続き元Javaプログラマー村上です。
前回は文字列⇔数値の変換コストについて書かせてもらいましたが、
今回は文字列結合についてその効率性を検証してみようかなと思います。
Javaにおける文字列結合は次の4つの方法があります。
プラス演算子
1 2 3 |
String s1 = "aaa"; String s2 = "bbb"; String s = s1 + s2; |
String#concat()
1 2 3 |
String s1 = "aaa"; String s2 = "bbb"; String s = s1.concat(s2); |
StringBuffer
1 2 3 4 5 6 |
String s1 = "aaa"; String s2 = "bbb"; StringBufferbuf = new StringBuffer(); buf.append(s1); buf.append(s2); String s = buf.toString(); |
StringBuilder
1 2 3 4 5 6 |
String s1 = "aaa"; String s2 = "bbb"; StringBuilder buf = new StringBuilder(); buf.append(s1); buf.append(s2); String s = buf.toString(); |
推奨は「StringBuffer」か「StringBuilder」でしょう。
今回はループ処理で文字列を結合する時の時間を測ってみます。
コードはこんな感じで
1 2 3 4 |
String str = ""; for (int i = 0; i < LOOP_COUNT; i++) { str = str + "hoge"; } |
単位はミリ秒です。
ループ100000回 | Java5 | Java6 | Java7 |
---|---|---|---|
プラス演算子 | 測定不能 | 20616 | 15989 |
String#concat() | 測定不能 | 10105 | 7987 |
StringBuffer | 11 | 2 | 2 |
StringBuilder | 9 | 2 | 1 |
処理時間の順位は予想どおりですが、処理時間はメッチャ差が付きましたね。
やっぱり推奨されているものを使うべきです。
ちなみにループ回数ですが、10万回を100万回にするとJava5と6はOutOfMemoryでしたが、同じメモリ容量でJava7は1000万回でも動作しました。
Javaの進化はすごい!!
検証はループ内で文字列を結合していくコードにしましたが、単純な文字列結合の場合はどうなるかも検証してみました。
コードはこんな感じです。
プラス演算子
1 2 3 4 5 |
for (int i = 0; i < LOOP_COUNT; i++) { String s1 = "aaa"; String s2 = "bbb"; String s = s1 + s2; } |
StringBuffer
1 2 3 4 5 6 7 8 |
for (int i = 0; i < LOOP_COUNT; i++) { String s1 = "aaa"; String s2 = "bbb"; StringBufferbuf = new StringBuffer(); buf.append(s1); buf.append(s2); String s = buf.toString(); } |
検証コードは結合する文字を200文字ぐらいに増やしてます。
結果は下記の通り
単位はミリ秒です。
ループ100000回 | Java5 | Java6 | Java7 |
---|---|---|---|
プラス演算子 | 467 | 353 | 286 |
StringBuffer | 744 | 445 | 493 |
StringBuilder | 462 | 351 | 282 |
Stringのプラス演算子は裏ではStringBuilderで文字列結合してるみたいなので、プラス演算子とStringBufferではプラス演算子の方が速くなるんですね。
一行で文字列結合する場合はプラス演算子を使用しても問題無い気がしますね。