Ich überlege, einen RFE (Antrag auf Erweiterung) an die Oracle Bug Database zu senden, die die String-Verkettungsleistung erheblich erhöhen soll. Aber bevor ich das tue, möchte ich gerne die Kommentare der Experten hören, ob das Sinn macht.Kann java.lang.String.concat verbessert werden?
Die Idee basiert auf der Tatsache, dass die vorhandene String.concat (String) auf 2 Zeichenfolgen zweimal schneller als StringBuilder funktioniert. Das Problem besteht darin, dass es keine Methode gibt, 3 oder mehr Zeichenfolgen zu verketten. Externe Methoden können das nicht, da String.concat einen privaten Paketkonstruktor String(int offset, int count, char[] value)
verwendet, der das char-Array nicht kopiert, sondern direkt verwendet. Dies gewährleistet eine hohe String.concat-Leistung. Im selben Paket kann StringBuilder diesen Konstruktor immer noch nicht verwenden, da dann das char-Array des Strings für Änderungen offen gelegt wird.
Ich schlage vor, die folgenden Methoden zu String
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)
Nachricht hinzuzufügen: diese Art von Überlastung ist für Effizienz in EnumSet.of, verwendet.
Dies ist die Implementierung eines des Verfahrens, andere funktionieren auf die gleiche Art und Weise
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);
}
Auch nach diesen Methoden String hinzugefügt werden, Java-Compiler für
String s = s1 + s2 + s3;
Lage sein wird, Aufbau effizienter
String s = String.concat(s1, s2, s3);
statt Strom ineffizient
String s = (new StringBuilder(String.valueOf(s1))).append(s2).append(s3).toString();
UPDATE Leistungstest. Ich lief es auf meinem Notebook Intel Celeron 925, Verkettung von 3 Strings, meine String2-Klasse emuliert genau, wie es in echten java.lang.String wäre. Stringlängen werden so gewählt, dass StringBuilder unter den ungünstigsten Bedingungen platziert werden kann, dh wenn die interne Pufferkapazität bei jedem Append erweitert werden muss, während concat immer nur char [] erstellt.
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);
}
}
auf 1.000.000 Iterationen die Ergebnisse sind:
version 1 = ~200 ms
version 2 = ~400 ms
String Buffer kann viel mehr schneller sein, dass Sie –