Tôi đã nghiên cứu một câu hỏi đã được trình bày cho tôi: Cách viết một hàm lấy chuỗi làm đầu vào và trả về một chuỗi có dấu cách giữa các ký tự. Hàm này được viết để tối ưu hóa hiệu suất khi nó được gọi là hàng ngàn lần mỗi giây.String.Ginin vấn đề hiệu suất trong C#
Tôi biết rằng .net có chức năng được gọi là
String.Join
, mà tôi có thể chuyển vào ký tự khoảng trắng làm dấu tách cùng với chuỗi gốc.Chặn sử dụng
String.Join
, tôi có thể sử dụng lớpStringBuilder
để nối thêm dấu cách sau mỗi ký tự.Cách khác để thực hiện tác vụ này là khai báo một mảng ký tự với 2 * n-1 ký tự (Bạn phải thêm ký tự n-1 cho dấu cách). Mảng ký tự có thể được điền vào một vòng lặp và sau đó được chuyển đến chuỗi
constructor
.
Tôi đã viết một số mã .net chạy mỗi thuật toán một triệu lần mỗi tham số "Hello, World"
và đo thời gian thực thi. Phương pháp (3) là nhiều, nhanh hơn nhiều so với (1) hoặc (2).
Tôi biết rằng (3) nên rất nhanh vì nó tránh tạo ra bất kỳ tham chiếu chuỗi bổ sung nào để thu gom rác, nhưng có vẻ như với chức năng tích hợp .net như String.Join
sẽ mang lại hiệu suất tốt. Tại sao sử dụng String.Join
chậm hơn nhiều so với thực hiện công việc bằng tay?
public static class TestClass
{
// 491 milliseconds for 1 million iterations
public static string Space1(string s)
{
return string.Join(" ", s.AsEnumerable());
}
//190 milliseconds for 1 million iterations
public static string Space2(string s)
{
if (s.Length < 2)
return s;
StringBuilder sb = new StringBuilder();
sb.Append(s[0]);
for (int i = 1; i < s.Length; i++)
{
sb.Append(' ');
sb.Append(s[i]);
}
return sb.ToString();
}
// 50 milliseconds for 1 million iterations
public static string Space3(string s)
{
if (s.Length < 2)
return s;
char[] array = new char[s.Length * 2 - 1];
array[0] = s[0];
for (int i = 1; i < s.Length; i++)
{
array[2*i-1] = ' ';
array[2*i] = s[i];
}
return new string(array);
}
Cập nhật: Tôi đã thay đổi dự án của tôi để "phát hành" chế độ và cập nhật lần trôi qua tôi trong câu hỏi cho phù hợp.
Nếu bạn đang so sánh hiệu suất, bạn có trong phiên bản xây dựng với tối ưu hóa trên? – Servy
Khi bạn tạo StringBuilder trong tùy chọn 2, bạn có thể truyền trong dung lượng ban đầu là 2 * n-1, điều này sẽ ngăn không cho nó tạo lại và sao chép bộ đệm nội bộ của nó trên các chuỗi lớn hơn. – Servy
@Servy, tôi chỉ đơn giản là tạo ra một dự án Console mới trong Visual Studio 2010. –