Bạn phải cân bằng khả năng đọc với chức năng.
Hãy nói rằng bạn có những điều sau đây:
String str = "foo";
str += "bar";
if(baz) str += "baz";
này sẽ tạo ra 2 nhà xây dựng chuỗi (nơi bạn chỉ cần 1, thực sự) cộng với một đối tượng chuỗi bổ sung cho thời gian chuyển tiếp. Bạn sẽ hiệu quả hơn nếu bạn đã đi:
StringBuilder strBuilder = new StringBuilder("foo");
strBuilder.append("bar");
if(baz) strBuilder.append("baz");
String str = strBuilder.toString();
Nhưng như một vấn đề về phong cách, tôi nghĩ cái đầu tiên trông rất ổn. Lợi ích hiệu suất của việc tạo một đối tượng đơn giản có vẻ rất nhỏ đối với tôi.Bây giờ, nếu thay vì 3 chuỗi, bạn có 10, hoặc 20, hoặc 100, tôi sẽ nói hiệu suất vượt trội hơn phong cách. Nếu nó đã được trong một vòng lặp, chắc chắn tôi muốn sử dụng xây dựng chuỗi, nhưng tôi nghĩ chỉ là một vài dây là tốt để làm 'sloppy' cách để làm cho mã trông sạch hơn. Nhưng ... cái này có một cái bẫy rất nguy hiểm ẩn trong đó! Đọc bên dưới (tạm dừng để xây dựng hồi hộp ... dun dun dunnnn)
Có những người nói luôn sử dụng trình tạo chuỗi rõ ràng. Một lý do là mã của bạn sẽ tiếp tục phát triển, và nó thường sẽ làm như vậy theo cách tương tự như nó đã sẵn sàng (tức là họ sẽ không dành thời gian để cấu trúc lại.) Vì vậy, bạn kết thúc với 10 hoặc 20 câu lệnh đó mỗi lần tạo người xây dựng của riêng họ khi bạn không cần. Vì vậy, để ngăn chặn điều này ngay từ đầu, họ nói luôn sử dụng một người xây dựng rõ ràng. Vì vậy, trong khi trong ví dụ của bạn, nó sẽ không được đặc biệt nhanh hơn, khi ai đó trong tương lai quyết định họ muốn phần mở rộng tập tin ở cuối, hoặc một cái gì đó như thế, nếu họ tiếp tục sử dụng chuỗi nối thay vì StringBuilder, cuối cùng họ sẽ gặp phải vấn đề về hiệu suất.
Chúng tôi cũng cần suy nghĩ về tương lai. Giả sử bạn đang tạo mã Java trở lại trong JDK 1.1 và bạn có phương pháp sau:
public String concat(String s1, String s2, String s3) {
return s1 + s2 + s3;
}
Lúc đó, nó sẽ chậm vì StringBuilder không tồn tại.
Sau đó, trong JDK 1.3 bạn quyết định làm cho nó nhanh hơn bằng cách sử dụng StringBuffer (StringBuilder vẫn chưa tồn tại). Bạn làm điều này:
public String concat(String s1, String s2, String s3) {
StringBuffer sb = new StringBuffer();
sb.append(s1);
sb.append(s2);
sb.append(s3);
return sb.toString();
}
Nó nhanh hơn rất nhiều. Tuyệt vời!
Bây giờ JDK 1.5 đi ra, và cùng với nó đến StringBuilder (đó là nhanh hơn so với StringBuffer) và transation tự động
return s1 + s2 + s3;
để
return new StringBuilder().append(s1).append(s2).append(s3).toString();
Nhưng bạn không có được hiệu suất này vì bạn đang sử dụng StringBuffer một cách rõ ràng. Vì vậy, bằng cách thông minh, bạn đã gây ra một hit hiệu suất khi Java thông minh hơn bạn. Vì vậy, bạn phải ghi nhớ rằng có những điều trên mạng bạn sẽ không nghĩ đến.
Xem nội dung thú vị này: http://www.precisejava.com/javaperf/j2se/StringAndStringBuffer.htm – Zaki
@Zaki: Những điểm chuẩn này thực sự không hữu ích về mặt thực tế. Có gì hữu ích hơn là lập hồ sơ ứng dụng của bạn để xem liệu ứng dụng có thực sự có nút cổ chai hiệu suất hay không. Và chọn các thuật toán và cấu trúc dữ liệu thích hợp cho trường hợp sử dụng cụ thể của bạn. – mellamokb