・Stringクラスを使用して文字列の連結処理を行うと、毎回Stringオブジェクトが生成される。
・これはオーバーヘッドとなるので、StringBuilderやStringBufferクラスを使用すべきと言われている。
・私は「そのくらいのオーバーヘッドはたいしたことないだろ」とこれらのクラスは使用していない。もちろん回数が多い場合は使用すべきであるが、(私には)そのような状況はあまりない。
・これらのクラスを使用すると、ソースコードが見にくくなるのがちょっと問題。
・どのくらい違うのか計測してみた。
・大雑把に言って、Stringを直接操作した場合は10倍以上かかっている。
・しかしそもそも絶対時間は大きくはないので、回数が少ない場合は、String直接操作でよいと考える。
・StringBuffer(StringBuilder)を使用する場合の判断に使っていただきたい。
・なお百万回になると、StringBufferの方がStringBuilderよりも速くなっている。理由は(私には)不明。
・ここでは一回の結果を示すが、何度やっても傾向は同じである。
・StringBufferとStringBuilderの違い。前者はスレッドセーフで、後者はスレッドセーフではない。後者が新しい。
・なぜスレッドセーフにしなかったかと言えば、スレッドで使う場合は非常に少なく、それがためにスピードを落としたくないということ(と想像する)。
・StringBuilderをスレッドで使いたい場合は、自分で制御するようにしなさいということ。
package jp.avaj.lib.algo;
import java.util.Date;
import jp.avaj.lib.test.L;
class Tips0016 {
private static int CNT0;
private static final int CNT1 = 100; //
public static void main(String[] args) {
L.p("==== 一万回");
CNT0 = 10000;
execString();
execStringBuilder();
execStringBuffer();
L.p("==== 十万回");
CNT0 = 100000;
execString();
execStringBuilder();
execStringBuffer();
L.p("==== 百万回");
CNT0 = 1000000;
execString();
execStringBuilder();
execStringBuffer();
}
private static void execString() {
long start = (new Date()).getTime();
for (int i=0; i<CNT0; i++) {
String s = "";
for (int j=0; j<CNT1; j++) {
s += "aaa";
}
}
long end = (new Date()).getTime();
diff("String",start,end);
}
private static void execStringBuilder() {
long start = (new Date()).getTime();
for (int i=0; i<CNT0; i++) {
StringBuilder sb = new StringBuilder();
for (int j=0; j<CNT1; j++) {
sb.append("aaa");
}
}
long end = (new Date()).getTime();
diff("StringBuilder",start,end);
}
private static void execStringBuffer() {
long start = (new Date()).getTime();
for (int i=0; i<CNT0; i++) {
StringBuffer sb = new StringBuffer();
for (int j=0; j<CNT1; j++) {
sb.append("aaa");
}
}
long end = (new Date()).getTime();
diff("StringBuffer",start,end);
}
private static void diff(String desc,long start,long end) {
L.p(desc+"="+(end-start));
}
}
実行結果は次のとおり。
==== 一万回
String=230
StringBuilder=31
StringBuffer=52
==== 十万回
String=1383
StringBuilder=149
StringBuffer=352
==== 百万回
String=12336
StringBuilder=1433
StringBuffer=1388