StringBufferクラスは、文字列を動的に追加/挿入ができるクラスで、Javaではかなり使われるクラスの1つです。 StringBuilderクラスは、StringBufferと同じ機能を提供しますが、StringBufferよりも速度が速い代わりに、 スレッドセーフではないのが特徴です。 では、プログラミングをする上で、どのような場面でどれを使い分ければいいのか。 また、何度も格納する文字列等をリセットする場合は、新たにインスタンスを作り直したほうが速いのか、 それともdeleteメソッドで内容をすべて削除したほうが速いのか、疑問に思ったので、実験してみました。
以下が、実験に使用したプログラムです。
import java.util.Date;
public class StringBuilderTest {
/** ループ回数 */
private static final int roop = 100;
/** appendする値 */
private static String sbValue = "abcdefghijklmnopqrstuvwxyz";
public static void main(String[] args) {
new StringBuilderTest();
}
private StringBuilderTest() {
// 毎回StringBufferインスタンスを作る場合
createStringBufferEachTime();
// 毎回StringBuilderインスタンスを作る場合
createStringBuilderEachTime();
// 毎回StringBufferの内容をdeleteする場合
deleteStringBufferValueEachTime();
// 毎回StringBuilderの内容をdeleteする場合
deleteStringBuilderValueEachTime();
}
private void createStringBufferEachTime() {
long startTime = new Date().getTime();
StringBuffer sb;
for (int i=0 ; i<roop ; i++) {
sb = new StringBuffer();
sb.append(sbValue);
sb = null;
}
long take = new Date().getTime() - startTime;
System.out.println("createStringBufferEachTime() : " +
take + " milli seconds");
}
private void createStringBuilderEachTime() {
long startTime = new Date().getTime();
StringBuilder sb;
for (int i=0 ; i<roop ; i++) {
sb = new StringBuilder();
sb.append(sbValue);
sb = null;
}
long take = new Date().getTime() - startTime;
System.out.println("createStringBuilderEachTime : " +
take + " milli seconds");
}
private void deleteStringBufferValueEachTime() {
long startTime = new Date().getTime();
StringBuffer sb = new StringBuffer();
for (int i=0 ; i<roop ; i++) {
sb.append(sbValue);
sb.delete(0, sb.length());
}
long take = new Date().getTime() - startTime;
System.out.println("deleteStringBufferValueEachTime : " +
take + " milli seconds");
}
private void deleteStringBuilderValueEachTime() {
long startTime = new Date().getTime();
StringBuilder sb = new StringBuilder();
for (int i=0 ; i<roop ; i++) {
sb.append(sbValue);
sb.delete(0, sb.length());
}
long take = new Date().getTime() - startTime;
System.out.println("deleteStringBuilderValueEachTime() : " +
take + " milli seconds");
}
}
1回目
createStringBufferEachTime() : 1 milli seconds createStringBuilderEachTime : 0 milli seconds deleteStringBufferValueEachTime : 1 milli seconds deleteStringBuilderValueEachTime() : 0 milli seconds
2回目
createStringBufferEachTime() : 0 milli seconds createStringBuilderEachTime : 0 milli seconds deleteStringBufferValueEachTime : 1 milli seconds deleteStringBuilderValueEachTime() : 0 milli seconds
3回目
createStringBufferEachTime() : 0 milli seconds createStringBuilderEachTime : 1 milli seconds deleteStringBufferValueEachTime : 0 milli seconds deleteStringBuilderValueEachTime() : 0 milli seconds
どうやら、この条件では、どれもあまり差が見られないようですが、 StringBuilderを使って毎回deleteする方法が、一番早いように見えます。
1回目
createStringBufferEachTime() : 13 milli seconds createStringBuilderEachTime : 6 milli seconds deleteStringBufferValueEachTime : 8 milli seconds deleteStringBuilderValueEachTime() : 3 milli seconds
2回目
createStringBufferEachTime() : 13 milli seconds createStringBuilderEachTime : 6 milli seconds deleteStringBufferValueEachTime : 7 milli seconds deleteStringBuilderValueEachTime() : 5 milli seconds
3回目
createStringBufferEachTime() : 21 milli seconds createStringBuilderEachTime : 6 milli seconds deleteStringBufferValueEachTime : 7 milli seconds deleteStringBuilderValueEachTime() : 4 milli seconds
今回の条件の場合、毎回StringBufferを作成する場合、最も遅いようです。 そしてそしてここでもやはりStringBuilderを毎回deleteする場合が最も早いようです。
1回目
createStringBufferEachTime() : 22 milli seconds createStringBuilderEachTime : 12 milli seconds deleteStringBufferValueEachTime : 9 milli seconds deleteStringBuilderValueEachTime() : 6 milli seconds
2回目
createStringBufferEachTime() : 21 milli seconds createStringBuilderEachTime : 12 milli seconds deleteStringBufferValueEachTime : 10 milli seconds deleteStringBuilderValueEachTime() : 5 milli seconds
3回目
createStringBufferEachTime() : 22 milli seconds createStringBuilderEachTime : 13 milli seconds deleteStringBufferValueEachTime : 10 milli seconds deleteStringBuilderValueEachTime() : 5 milli seconds
やはり毎回StringBufferを作成する処理が最も遅く、 毎回StringBuilderの内容をdeleteする処理が最も早かったです。
処理の回数や、追加する文字列の量が増えると、 StringBufferを使うのとStringBuilderを使うのとでは、かなりの速度の違いが生じる。
処理の回数や、追加する文字列の量が増えると、 毎回新たにインスタンスを作り直す場合のほうが、毎回すべての格納している文字列をdeleteするよりも、 やや時間が掛かる。