Giải thích của bạn tại sao nó không hiệu quả là chính xác, ít nhất là trong các ngôn ngữ mà tôi quen thuộc (C, Java, C #), mặc dù tôi không đồng ý rằng việc thực hiện nối chuỗi chuỗi là rất phổ biến. Trong đoạn code C # tôi làm việc trên, có sử dụng dồi dào StringBuilder
, String.Format
vv đó là tất cả bộ nhớ tiết kiệm techiniques để tránh quá phân bổ lại.
Vì vậy, để có được câu trả lời cho câu hỏi của bạn, chúng ta phải đặt một câu hỏi khác: nếu nó không bao giờ thực sự là một vấn đề để nối chuỗi, tại sao các lớp lại thích StringBuilder
và StringBuffer
tồn tại ? Tại sao việc sử dụng các lớp như vậy được bao gồm trong các sách và lớp lập trình bán sơ cấp? Tại sao lời khuyên tối ưu hóa trưởng thành dường như rất nổi bật?
Nếu hầu hết các nhà phát triển nối chuỗi là dựa trên câu trả lời của họ hoàn toàn dựa trên kinh nghiệm, thì hầu hết sẽ nói rằng nó không bao giờ tạo ra sự khác biệt và sẽ tránh sử dụng các công cụ như vậy để "dễ đọc hơn" for (int i=0; i<1000; i++) { strA += strB; }
. Nhưng họ không bao giờ đo lường nó.
Câu trả lời thực sự cho câu hỏi này có thể được tìm thấy trong câu trả lời SO này , điều này cho thấy rằng trong một trường hợp, khi nối 50.000 chuỗi (tùy thuộc vào ứng dụng của bạn, có thể là một sự xuất hiện phổ biến), ngay cả những câu nhỏ, dẫn đến hiệu suất 1000 lần .
Nếu hiệu suất theo nghĩa đen hoàn toàn không có nghĩa gì cả, thì tất cả đều có nghĩa là bỏ đi. Nhưng tôi không đồng ý rằng việc sử dụng các lựa chọn thay thế (StringBuilder) là khó khăn hoặc ít đọc hơn , và do đó sẽ là một thực tiễn lập trình hợp lý không nên gọi biện pháp phòng thủ "tối ưu hóa sớm".
CẬP NHẬT:
Tôi nghĩ những gì nó đi xuống, là biết nền tảng của bạn và làm theo các thực tiễn tốt nhất của nó, đáng buồn là không phổ quát . Hai ví dụ từ hai "ngôn ngữ hiện đại" khác nhau:
- Trong một câu trả lời SO khác , các đặc tính hiệu suất ngược lại chính xác (mảng.join vs + =) đôi khi được tìm thấy trong JavaScript . Trong một số trình duyệt, nối chuỗi dường như được tối ưu hóa tự động và trong các trường hợp khác thì không. Vì vậy, khuyến nghị (ít nhất là trong câu hỏi SO đó), là chỉ cần nối và không lo lắng về nó.
- Trong một trường hợp khác, trình biên dịch Java có thể tự động thay thế phép nối bằng một cấu trúc hiệu quả hơn như StringBuilder. Tuy nhiên, như những người khác đã chỉ ra, điều này là không xác định, không được bảo đảm và sử dụng StringBuilder không ảnh hưởng đến khả năng đọc. Trong trường hợp cụ thể này, tôi có xu hướng đề nghị chống lại việc sử dụng phép nối cho các bộ sưu tập lớn hoặc dựa vào một hành vi trình biên dịch Java không xác định. Tương tự, trong .NET, không bao giờ tối ưu hóa loại sắp xếp .
Đó không hẳn là một tội lỗi chính đáng khi không biết mọi sắc thái của mọi nền tảng ngay lập tức, nhưng bỏ qua các vấn đề nền tảng quan trọng như thế này gần như sẽ chuyển từ Java sang C ++ và không quan tâm đến việc giải phóng bộ nhớ.