[Java] 演算子: +演算子による文字列結合(StringBuilder)
+演算子による文字列連結は非効率とのこと。
- 新しめの Java での単発の文字列連結は、内部的に StringBuilder オブジェクトに変換されるためシンプルに+演算子を使うべき。
- ループ内の文字列連結では StringBuilder が繰り返し生成されるため非効率になる。
以下同じ出力を得るための試行。
% java --version
openjdk 16 2021-03-16
OpenJDK Runtime Environment (build 16+36-2231)
OpenJDK 64-Bit Server VM (build 16+36-2231, mixed mode, sharing)
Contents
+演算子による文字列連結
package com.example.arrayloop;
public class ArrayLoop {
public static void main(String[] args) throws Exception {
var start = System.currentTimeMillis();
int[] array = {50, 60, 70, 80};
for (int mps : array) {
var kmh = mps * 3600 / 1000;
msg = "最大瞬間風速" + mps + "m = 時速" + kmh + "km";
System.out.println(msg);
}
var end = System.currentTimeMillis();
System.out.println((end - start) + "ミリ秒");
}
}
実行結果
最大瞬間風速50m = 時速180km
最大瞬間風速60m = 時速216km
最大瞬間風速70m = 時速252km
最大瞬間風速80m = 時速288km
18ミリ秒
一度の連結で、内部的には「元の文字列、連結する文字列、結果文字列」と合計3個の String オブジェクトを生成している。
ループで連結回数が増えた場合には、ガベージコレクションの増大に繋がり無視できなくなる。
StringBuilder
package com.example.arrayloop;
public class ArrayLoop {
private static String msg;
public static void main(String[] args) throws Exception {
var start = System.currentTimeMillis();
StringBuilder msg = new StringBuilder();
int[] array = {50, 60, 70, 80};
for (int mps : array) {
var kmh = mps * 3600 / 1000;
msg.append("最大瞬間風速").append(mps).append("m = 時速").append(kmh).append("km").append("\n");
setMsg(msg.toString());
}
System.out.println(msg);
var end = System.currentTimeMillis();
System.out.println((end - start) + "ミリ秒");
}
private static void setMsg(String msgString) {
msg = msgString;
}
}
実行結果
最大瞬間風速50m = 時速180km
最大瞬間風速60m = 時速216km
最大瞬間風速70m = 時速252km
最大瞬間風速80m = 時速288km
1ミリ秒
補遺
- Stringbuffer クラスは、さらに排他制御を提供する。よってより低速。