Java8時代の文字列結合のまとめが気になったので試してみた
元ネタはこちら
だいぶ今更感がありますけど、気になったことが合ったので試してみました。
気になったこと1
データ量が多くなったら急に性能が落ちるケースってあるのか?気になったこと2
一応SIer所属なので、「漢は黙ってStringBuffer」も比較対象に加えたい。
というわけで、きしださんの作ったソースのコピペ をベースに、StringBufferで結合する素敵メソッドを追加。
それに対して文字列リストの要素数を1倍、10倍、100倍のケースで測ってみました。
まずはオリジナルの要素数で。
stringJoin:1812ms
stringBuilderJoinMem:958ms
stringArrayJoining:686ms
charBufferJoin:773ms
stringBufferJoin:1240ms
これはきしださんの結果と大体一致しています。
String#joinを使われるよりは、StringBufferの方がマシというところでしょうか。
次に文字列の要素数を10倍にして実行。
予想ではだいたい10倍位の時間になるはずですが。。。
stringJoin:18484ms
stringBuilderJoinMem:10775ms
stringArrayJoining:8595ms
charBufferJoin:13221ms
stringBufferJoin:12630ms
アイエエエ!?CharBufferナンデ!?
要素数が10倍になったら処理時間が20倍くらいになってます。
まさかのStringBufferよりも遅いという結末。
思い当たるフシとして、allocateのサイズが割りと適当なこと。
そこで、allocateの引数を90000(適当な数値)結合した文字列の長さに合わせた79995バイトに変更してみました。
CharBuffer buffer = CharBuffer.allocate(79995);
再測定した結果はこんな感じです。
stringJoin:18971ms
stringBuilderJoinMem:10594ms
stringArrayJoining:8212ms
charBufferJoin:12023ms
stringBufferJoin:12849ms
StringBufferより辛うじて早いけれど・・・という感じです。
ちなみにその後に行った100倍の結果はこちら。
stringJoin:197357ms
stringBuilderJoinMem:111888ms
stringArrayJoining:89730ms
charBufferJoin:129791ms
stringBufferJoin:132432ms
こちらは比較的予想通りの結果です。
CharBufferも前回のリミット見直しのおかげでStringBufferより早いです。
まとめ
試してみたなりのまとめです。
- カツカツな性能が求められていない限り、StringBuilderが安定。
- CharBufferのリミットはしっかり設定しよう。
本来は文字列結合だけの目的で使うクラスじゃないのでしょうが・・・。 - あれ、Java8の要素があまりないよ?
ま、まぁ、+演算子で結合というような事をしない限りは、文字列結合の速度で問題にはならない気がします。
補足
ByteBufferは使うけど、CharBuffer使ったの初めてかも・・・。