Đi lớp này ví dụ:
public class Tmp {
public static void main(String[] args) {
ArrayList<Integer> numbers = new ArrayList<Integer>();
numbers.add(1);
}
}
Nó biên dịch xuống này:
Compiled from "Tmp.java"
public class Tmp extends java.lang.Object{
public Tmp();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: new #2; //class java/util/ArrayList
3: dup
4: invokespecial #3; //Method java/util/ArrayList."<init>":()V
7: astore_1
8: aload_1
9: iconst_1
10: invokestatic #4; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
13: invokevirtual #5; //Method java/util/ArrayList.add:(Ljava/lang/Object;)Z
16: pop
17: return
}
Trong khi lớp này:
public class Tmp {
public static void main(String[] args) {
List<Integer> numbers = new ArrayList<Integer>();
numbers.add(1);
}
}
biên dịch xuống này:
Compiled from "Tmp.java"
public class Tmp extends java.lang.Object{
public Tmp();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: new #2; //class java/util/ArrayList
3: dup
4: invokespecial #3; //Method java/util/ArrayList."<init>":()V
7: astore_1
8: aload_1
9: iconst_1
10: invokestatic #4; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
13: invokeinterface #5, 2; //InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
18: pop
19: return
}
Bạn sẽ thấy rằng điểm khác biệt duy nhất là sử dụng số ArrayList
) gọi invokevirtual
và một số khác (sử dụng List
sử dụng) invokeinterface
.invokeinterface
thực sự là một mái tóc chậm hơn invokevirtual
(~ 38% theo số this guy). Đây là apparently do tối ưu hóa mà JVM có thể thực hiện khi tìm kiếm thông qua các bảng phương thức ảo của lớp bê tông so với các bảng phương thức của giao diện. Vì vậy, những gì bạn đang nói là thực sự đúng sự thật. Yêu cầu giao diện là chậm hơn lời gọi lớp bê tông.
Tuy nhiên, bạn phải cân nhắc loại tốc độ mà chúng ta đang nói đến. Đối với 100.000.000 lời gọi, sự khác biệt thực tế là 0,03 giây. Vì vậy, bạn phải có tấn các lời gọi để thực sự có tốc độ giảm đáng kể.
Mặt khác, như @ChinBoon chỉ ra, mã hóa giao diện giúp việc sử dụng mã của bạn trở nên dễ dàng hơn, đặc biệt nếu mã của bạn trả về một số loại
List
. Vì vậy, trong số
lớn nhất phần lớn các trường hợp, dễ dàng mã hóa
đến nay vượt quá chi phí hiệu suất tương đối.
gia tăng sau khi đọc @ bình luận MattQuigley và cho nó một suy nghĩ trên đường về nhà
gì tất cả điều này có nghĩa là đây không phải là điều bạn nên lo lắng về quá nhiều. Mọi lợi ích hoặc hình phạt về hiệu suất có thể là rất nhỏ.
Xin lưu ý, việc sử dụng giao diện cho các loại trả lại và thông số của bạn về phương pháp là một ý tưởng rất hay. Điều đó cho phép bạn và bất kỳ ai sử dụng mã của bạn để sử dụng bất kỳ việc thực hiện nào của List
phù hợp nhất với nhu cầu của họ. Ví dụ của tôi cũng cho thấy rằng, nếu bạn tình cờ sử dụng phương thức trả về List
, 99% thời gian, bạn là không phải là tốt hơn khi bỏ nó vào một lớp cụ thể chỉ để tăng hiệu suất. Thời gian cần để đúc sẽ có khả năng lớn hơn mức tăng hiệu suất.
Điều đó đang được nói, ví dụ này cũng cho thấy rằng, đối với biến số cục bộ, bạn thực sự nên sử dụng lớp bê tông thay vì giao diện. Nếu phương pháp duy nhất bạn sử dụng là phương pháp trên List
, thì bạn có thể chuyển đổi các lớp triển khai mà không có tác dụng phụ. Ngoài ra, bạn sẽ có quyền truy cập vào các phương pháp cụ thể triển khai nếu bạn cần chúng. Thêm vào đó là một tăng hiệu suất nhỏ.
tl; dr
Luôn luôn sử dụng giao diện với nhiều loại lợi nhuận và các thông số về phương pháp. Bạn nên sử dụng các lớp cụ thể cho các biến cục bộ. Nó mang lại hiệu suất nhỏ và không mất chi phí để chuyển đổi các triển khai nếu các phương thức duy nhất bạn sử dụng có trên giao diện. Cuối cùng, bạn không nên lo lắng quá nhiều. (Ngoại trừ loại trả lại và thông số. Điều quan trọng.)
Ai là người đã nói với bạn rằng nó sẽ "làm tổn thương hiệu suất"? Bạn có lẽ nên xem xét bỏ qua lời khuyên từ anh/cô ấy trong tương lai. –