Tôi đang xem xét việc gửi một RFE (yêu cầu nâng cao) lên cơ sở dữ liệu Oracle Bug được cho là tăng đáng kể hiệu năng nối chuỗi. Nhưng trước khi tôi làm điều đó tôi muốn nghe ý kiến của các chuyên gia về việc liệu nó có ý nghĩa hay không.Có thể cải thiện java.lang.String.concat không?
Ý tưởng được dựa trên thực tế là String.concat (String) hiện có hoạt động nhanh hơn hai lần trên 2 chuỗi so với StringBuilder. Vấn đề là không có phương pháp để nối 3 hoặc nhiều chuỗi. Các phương thức bên ngoài không thể làm điều này vì String.concat sử dụng một hàm tạo riêng tư gói String(int offset, int count, char[] value)
mà không sao chép mảng char mà sử dụng nó trực tiếp. Điều này đảm bảo hiệu suất String.concat cao. Trong cùng một gói StringBuilder vẫn không thể sử dụng hàm tạo này vì sau đó mảng char của String sẽ được hiển thị để sửa đổi.
Tôi đề nghị bổ sung các phương pháp sau để 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)
Lưu ý: hình thức này quá tải được sử dụng trong EnumSet.of, cho hiệu quả.
Đây là việc thực hiện một trong những phương pháp, những người khác làm việc cùng một cách
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);
}
Ngoài ra, sau khi các phương pháp này được bổ sung vào String, trình biên dịch Java cho
String s = s1 + s2 + s3;
sẽ có thể xây dựng hiệu quả
String s = String.concat(s1, s2, s3);
thay vì hiện tại không hiệu quả
String s = (new StringBuilder(String.valueOf(s1))).append(s2).append(s3).toString();
CẬP NHẬT Kiểm tra hiệu suất. Tôi chạy nó trên máy tính xách tay Intel Celeron 925, nối 3 chuỗi, lớp String2 của tôi mô phỏng chính xác nó sẽ nằm trong java.lang.String thực sự như thế nào. Độ dài chuỗi được chọn sao cho đặt StringBuilder trong điều kiện không thuận lợi nhất, đó là khi cần mở rộng dung lượng bộ đệm bên trong của nó trên mỗi chắp thêm, trong khi concat luôn tạo char [] chỉ một lần.
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);
}
}
trên 1.000.000 lặp kết quả là:
version 1 = ~200 ms
version 2 = ~400 ms
Bộ đệm chuỗi có thể nhanh hơn rất nhiều mà bạn muốn đạt được –