Vì tôi không nghĩ câu trả lời ở đây bao gồm tất cả mọi thứ, tôi muốn thực hiện một bổ sung nhỏ ở đây.
Console.WriteLine(string format, params object[] pars)
các cuộc gọi string.Format
. '+' Hàm ý nối chuỗi. Tôi không nghĩ rằng điều này luôn luôn phải làm với phong cách; Tôi có xu hướng kết hợp hai phong cách tùy thuộc vào bối cảnh tôi đang ở.
Câu trả lời ngắn
Quyết định mà bạn phải đối mặt phải thực hiện với phân bổ chuỗi. Tôi sẽ cố gắng làm cho nó đơn giản.
Nói rằng bạn có
string s = a + "foo" + b;
Nếu bạn thực hiện điều này, nó sẽ đánh giá như sau:
string tmp1 = a;
string tmp2 = "foo"
string tmp3 = concat(tmp1, tmp2);
string tmp4 = b;
string s = concat(tmp3, tmp4);
tmp
đây không thực sự là một biến cục bộ, nhưng nó là tạm thời cho JIT (nó được đẩy trên ngăn xếp IL). Nếu bạn đẩy một chuỗi trên ngăn xếp (chẳng hạn như ldstr
trong IL cho bằng chữ), bạn đặt tham chiếu đến một con trỏ chuỗi trên ngăn xếp.
Khoảnh khắc bạn gọi concat
tham chiếu này trở thành một vấn đề, bởi vì không có bất kỳ tham chiếu chuỗi nào có sẵn có cả hai chuỗi. Điều này có nghĩa là .NET cần phân bổ một khối bộ nhớ mới và sau đó lấp đầy nó bằng hai chuỗi. Lý do đây là một vấn đề, là vì phân bổ tương đối đắt tiền.
Điều này thay đổi câu hỏi thành: Làm thế nào bạn có thể giảm số lượng concat
hoạt động?
Vì vậy, câu trả lời sơ bộ là: string.Format
cho> 1 concats, '+' sẽ hoạt động tốt chỉ với 1 concat. Và nếu bạn không quan tâm đến việc thực hiện tối ưu hóa hiệu suất vi mô,string.Format
sẽ hoạt động tốt trong trường hợp chung.
Một lưu ý về văn hóa
Và rồi có một thứ gọi là văn hóa ...
string.Format
cho phép bạn sử dụng CultureInfo
trong định dạng của bạn. Một toán tử đơn giản '+' sử dụng văn hóa hiện tại.
Điều này đặc biệt quan trọng nếu bạn đang viết định dạng tệp và f.ex. double
các giá trị mà bạn 'thêm' vào một chuỗi. Trên các máy khác nhau, bạn có thể kết thúc bằng các chuỗi khác nhau nếu bạn không sử dụng string.Format
với một rõ ràngCultureInfo
.
F.ex xem xét những gì xảy ra nếu bạn thay đổi một '.' đối với ',' trong khi viết tệp giá trị được phân tách bằng dấu phẩy ... bằng tiếng Hà Lan, dấu phân cách thập phân là dấu phẩy, vì vậy người dùng của bạn có thể nhận được một bất ngờ 'hài hước'.
Thêm câu trả lời
Nếu bạn không biết trước kích thước chính xác của chuỗi, tốt nhất nên sử dụng chính sách như thế này để tổng thể bộ đệm bạn sử dụng. Không gian chùng được lấp đầy trước tiên, sau đó dữ liệu được sao chép vào.
Phát triển có nghĩa là phân bổ một khối bộ nhớ mới và sao chép dữ liệu cũ vào bộ đệm mới. Khối bộ nhớ cũ sau đó có thể được phát hành. Bạn nhận được điểm mấu chốt tại thời điểm này: phát triển là một hoạt động đắt tiền.
Cách thực tế nhất để làm điều này là sử dụng chính sách tổng thể. Chính sách phổ biến nhất là tổng thể bộ đệm trong các quyền hạn của 2. Tất nhiên, bạn phải làm điều đó thông minh hơn một chút (vì sẽ không có ý nghĩa gì khi tăng từ 1,2,4,8 nếu bạn đã biết bạn cần 128 ký tự ) nhưng bạn có được hình ảnh. Chính sách này đảm bảo bạn không cần quá nhiều thao tác đắt tiền mà tôi đã mô tả ở trên.
StringBuilder
là một lớp về cơ bản tổng thể bộ đệm cơ bản trong quyền hạn của hai. string.Format
sử dụng StringBuilder
dưới mui xe.
Điều này làm cho quyết định của bạn trở thành sự đánh đổi cơ bản giữa tổng thể và bổ sung (-multipl) (văn hóa w / wo) hoặc chỉ phân bổ và nối thêm.
string.Format
mà không sử dụng bất kỳ tính năng định dạng tổng hợp nào (tức là chỉ đơn giản{0}
) và thay thế chúng bằng cách nối chuỗi nhanh hơn đáng kể. Tôi tự hỏi một kỳ tích như vậy là có thể đạt được với một trình viết lại IL hiện có như PostSharp.