可能な場合、Javaコンパイラが「+」演算子で連結された文字列をStringBuilderのインスタンスにコンパイルする方法と、同じコードにコンパイルされるため、単純な「+」演算子を使用する方が良い方法について読んでいました。(while ループで文字列を作成する場合を除きます。その場合は、明らかに StringBuilder を使用するのが最適です。)
また、文字列に対する .concat メソッドは常に最悪の選択であることも読みました( Findbugsによってバグにされたほどです!)。
そこで、Eclipse で小さな Java クラスを作成して自分でテストすることにしました。私の結果は私を少し驚かせました。私が見つけたのは、コマンド ラインと比較して、Eclipse に準拠して実行した場合、さまざまな方法が比較的高速または低速であるということでした。
最初の日食の結果は次のとおりです。
the total millis to concatenate with + was: 12154
the total millis to concatenate with .concat was: 8840
the total millis to concatenate with StringBuilder was: 11350
the total millis to concatenate with StringBuilder with a specified size was: 5611
そのため、サイズが指定されたEclipse StringBuilderが最速で、次に.concat(奇妙な)が続き、StringBuilderと「+」連結はほとんど同じでした。
ただし、コマンドラインでの私の結果は次のとおりです。
the total millis to concatenate with + was: 4139
the total millis to concatenate with .concat was: 8590
the total millis to concatenate with StringBuilder was: 10888
the total millis to concatenate with StringBuilder with a specified size was: 6033
そのため、コマンドラインからコンパイルして実行すると、「+」演算子が明らかに最速で、次にサイズ付きの文字列ビルダー、次に連結、最後は通常の文字列ビルダーでした!
これは私には意味がありません。明らかに、私が読んだすべてのスタックオーバーフローの回答は、 + 演算子が通常の古い StringBuilder インスタンスにコンパイルされることは時代遅れでなければならないということです。
ここで実際に何が起こっているか知っている人はいますか?
私はjdk1.7.0_07を使用していますが、Eclipseとコマンドラインの両方がまったく同じものを参照していることがわかります。私が知っている唯一の違いは、Eclipseが「javaw」を使用していることですが、私が読んだことから、違いはありません。
私が何も悪いことをしていないことを確認したい場合は、ここに私のテストクラスがありますが、それはしっかりしていると確信しています。
public class Test {
static final int LOOPS = 100000000;
static final String FIRST_STRING = "This is such";
static final String SECOND_STRING = " an awesomely cool ";
static final String THIRD_STRING = "to write string.";
/**
* @param args
*/
public static void main(String[] args) {
Test.plusOperator();
Test.dotConcat();
Test.stringBuilder();
Test.stringBuilderSizeSpecified();
}
public static void plusOperator() {
String localOne = FIRST_STRING;
String localTwo = SECOND_STRING;
String localThree = THIRD_STRING;
Calendar startTime = Calendar.getInstance();
for (int x = 0; x < LOOPS; x++) {
String toPrint = localOne + localTwo + localThree;
}
Calendar endTime = Calendar.getInstance();
System.out.println("the total millis to concatenate with + was: " +
(endTime.getTimeInMillis() - startTime.getTimeInMillis()));
}
public static void stringBuilder() {
String localOne = FIRST_STRING;
String localTwo = SECOND_STRING;
String localThree = THIRD_STRING;
Calendar startTime = Calendar.getInstance();
for (int x = 0; x < LOOPS; x++) {
StringBuilder toBuild = new StringBuilder()
.append(localOne)
.append(localTwo)
.append(localThree);
}
Calendar endTime = Calendar.getInstance();
System.out.println("the total millis to concatenate with StringBuilder was: " +
(endTime.getTimeInMillis() - startTime.getTimeInMillis()));
}
public static void stringBuilderSizeSpecified() {
String localOne = FIRST_STRING;
String localTwo = SECOND_STRING;
String localThree = THIRD_STRING;
Calendar startTime = Calendar.getInstance();
for (int x = 0; x < LOOPS; x++) {
StringBuilder toBuild = new StringBuilder(50)
.append(localOne)
.append(localTwo)
.append(localThree);
}
Calendar endTime = Calendar.getInstance();
System.out.println("the total millis to concatenate with StringBuilder with a specified size was: " +
(endTime.getTimeInMillis() - startTime.getTimeInMillis()));
}
public static void dotConcat() {
String localOne = FIRST_STRING;
String localTwo = SECOND_STRING;
String localThree = THIRD_STRING;
Calendar startTime = Calendar.getInstance();
for (int x = 0; x < LOOPS; x++) {
String toPrint = localOne.concat(localTwo).concat(localThree);
}
Calendar endTime = Calendar.getInstance();
System.out.println("the total millis to concatenate with .concat was: " +
(endTime.getTimeInMillis() - startTime.getTimeInMillis()));
}
}