Tôi đã cố gắng tạo phiên bản nhanh hơn của phương pháp String.equals() và bắt đầu bằng cách sao chép nó. Kết quả tôi thấy khá khó hiểu. Khi tôi chạy phiên bản đã dán bản sao, đã hẹn giờ và so sánh nó với phiên bản JVM, phiên bản JVM nhanh hơn. Sự khác biệt dao động từ 6x đến 34x nhanh hơn! Đơn giản chỉ cần đặt, chuỗi dài hơn, lớn hơn là sự khác biệt.Tại sao String.equals() nhanh hơn chính nó?
boolean equals(final char a[], final char b[]) {
int n = a.length;
int i = 0;
while (n-- != 0) {
if (a[i] != b[i]) return false;
i++;
}
return true;
}
public static void main() throws Exception {
String a = "blah balh balh";
String b = "blah balh balb";
long me = 0, jvm = 0;
Field value = String.class.getDeclaredField("value");
value.setAccessible(true);
final char lhs[] = (char[]) value.get(a);
final char rhs[] = (char[]) value.get(b);
for (int i = 0; i < 100; i++) {
long t = System.nanoTime();
equals(lhs, rhs);
t = System.nanoTime() - t;
me += t;
}
for (int i = 0; i < 100; i++) {
long t = System.nanoTime();
a.equals(b);
t = System.nanoTime() - t;
jvm += t;
}
System.out.println("me = " + me);
System.out.println("jvm = " + jvm);
}
Output:
me = 258931
jvm = 14991
Phương pháp equals() tôi đã viết là một phiên bản sao chép dán của một tìm thấy trong String.equals() phương pháp. Tại sao phiên bản JVM nhanh hơn phiên bản được sao chép. Nó có hiệu quả không?
Ai đó có thể giải thích lý do tại sao tôi thấy sự khác biệt rõ ràng như vậy?
PS: Nếu bạn muốn thấy sự khác biệt lớn, bạn có thể tạo chuỗi dài (thực sự, thực sự dài) chỉ với một ký tự khác nhau ở cuối.
Chỉ cần đoán, nhưng tôi nghĩ nó có thể liên quan đến tối ưu hóa thời gian chạy của JVM. Phiên bản gốc có thể được sử dụng rất nhiều trong nội bộ. Các phương thức được sử dụng thường xuyên có nhiều khả năng được tối ưu hóa bởi JVM. – Philipp
Tôi nghĩ 'jvm' tối ưu hóa' String.equals' thành chỉ lệnh lắp ráp tương đương dựa trên tên của nó chứ không phải là mã. Và có lẽ cũng inline nó. Khi bạn sao chép mã, tối ưu hóa sẽ bị mất. – doublep
@Phillip: Tôi cũng đoán vậy. Nếu đó là trường hợp thì JVM đang xử lý các lớp riêng của nó một cách đặc biệt! –