文字列連結のパフォーマンスを大幅に向上させる予定のOracle Bug DatabaseにRFE(拡張要求)を提出することを検討しています。しかし、私がそれをする前に、それが意味を成すかどうかについて専門家の意見を聞きたいと思います。java.lang.String.concatを改善できますか?
このアイデアは、既存のString.concat(String)がStringBuilderより2つの文字列で2倍速く動作するという事実に基づいています。問題は、3つ以上の文字列を連結する方法がないことです。 String.concatはcharプライベートコンストラクタString(int offset, int count, char[] value)
を使用するため、char配列はコピーされずに直接使用されるため、外部メソッドではこれを行うことはできません。これにより、高いString.concatパフォーマンスが保証されます。同じパッケージ内にあれば、StringBuilderはこのコンストラクターを使用できません。これは、Stringのchar配列が変更のために公開されるためです。
が、私は文字列
public static String concat(String s1, String s2)
public static String concat(String s1, String s2, String s3)
public static String concat(String s1, String s2, String s3, String s4)
public static String concat(String s1, String s2, String s3, String s4, String s5)
public static String concat(String s1, String... array)
注
に次のメソッドを追加することをお勧め:オーバーロードのこの種のは、効率のために、EnumSet.ofに使用されています。これは方法の一つの実装である、他の人が
同じように動作しpublic final class String {
private final char value[];
private final int count;
private final int offset;
String(int offset, int count, char value[]) {
this.value = value;
this.offset = offset;
this.count = count;
}
public static String concat(String s1, String s2, String s3) {
char buf[] = new char[s1.count + s2.count + s3.count];
System.arraycopy(s1.value, s1.offset, buf, 0, s1.count);
System.arraycopy(s2.value, s2.offset, buf, s1.count, s2.count);
System.arraycopy(s3.value, s3.offset, buf, s1.count + s2.count, s3.count);
return new String(0, buf.length, buf);
}
また、これらのメソッドはStringに追加された後、
String s = s1 + s2 + s3;
のためのJavaコンパイラのことができるようになります効率的に構築する
String s = String.concat(s1, s2, s3);
現在非効率ではなく
String s = (new StringBuilder(String.valueOf(s1))).append(s2).append(s3).toString();
UPDATEパフォーマンステスト。私は私のノートブックのIntel Celeron 925で実行しました.3つの文字列を連結して、私のString2クラスは実際のjava.lang.Stringにどうなるか正確にエミュレートします。ストリングの長さは、StringBuilderを最も不利な条件に置くように選択されます。つまり、concatは常にchar []を一度しか作成しませんが、それぞれの追加時に内部バッファー容量を拡張する必要があります。 1,000,000回の反復で
public class String2 {
private final char value[];
private final int count;
private final int offset;
String2(String s) {
value = s.toCharArray();
offset = 0;
count = value.length;
}
String2(int offset, int count, char value[]) {
this.value = value;
this.offset = offset;
this.count = count;
}
public static String2 concat(String2 s1, String2 s2, String2 s3) {
char buf[] = new char[s1.count + s2.count + s3.count];
System.arraycopy(s1.value, s1.offset, buf, 0, s1.count);
System.arraycopy(s2.value, s2.offset, buf, s1.count, s2.count);
System.arraycopy(s3.value, s3.offset, buf, s1.count + s2.count, s3.count);
return new String2(0, buf.length, buf);
}
public static void main(String[] args) {
String s1 = "1";
String s2 = "11111111111111111";
String s3 = "11111111111111111111111111111111111111111";
String2 s21 = new String2(s1);
String2 s22 = new String2(s2);
String2 s23 = new String2(s3);
long t0 = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
String2 s = String2.concat(s21, s22, s23);
// String s = new StringBuilder(s1).append(s2).append(s3).toString();
}
System.out.println(System.currentTimeMillis() - t0);
}
}
結果は以下のとおりです。
version 1 = ~200 ms
version 2 = ~400 ms
文字列バッファーをもっと速くすることができます。 –