Tôi có một chuỗi rất dài (60MB về kích thước), trong đó tôi cần tìm xem có bao nhiêu cặp '<' và '>' nằm trong đó.Làm thế nào có thể C# 's string.IndexOf thực hiện quá nhanh, 10 lần nhanh hơn bình thường cho vòng tìm?
Tôi đã cố gắng đầu tiên theo cách riêng của tôi:
char pre = '!';
int match1 = 0;
for (int j = 0; j < html.Length; j++)
{
char c = html[j];
if (pre == '<' && c == '>') //find a match
{
pre = '!';
match1++;
}
else if (pre == '!' && c == '<')
pre = '<';
}
Đoạn mã trên chạy trên chuỗi của tôi cho khoảng 1000 ms.
Sau đó, tôi cố gắng sử dụng string.IndexOf
int match2 = 0;
int index = -1;
do
{
index = html.IndexOf('<', index + 1);
if (index != -1) // find a match
{
index = html.IndexOf('>', index + 1);
if (index != -1)
match2++;
}
} while (index != -1);
Đoạn mã trên chạy chỉ khoảng 150 ms.
tôi tự hỏi sự kỳ diệu mà làm cho string.IndexOf
chạy quá nhanh là gì?
Mọi người đều có thể truyền cảm hứng cho tôi?
Sửa
Ok, theo câu trả lời @ BrokenGlass của. Tôi sửa đổi mã của tôi theo cách mà họ không kiểm tra các cặp, thay vào đó, họ kiểm tra có bao nhiêu '<' trong chuỗi.
for (int j = 0; j < html.Length; j++)
{
char c = html[j];
if (c == '>')
{
match1++;
}
}
mã trên chạy với giá khoảng 760 ms .
Sử dụng IndexOf
int index = -1;
do
{
index = html.IndexOf('<', index + 1);
if (index != -1)
{
match2++;
}
} while (index != -1);
Đoạn mã trên chạy trong khoảng 132 ms. vẫn rất nhanh.
Chỉnh sửa 2
Sau khi đọc @Jeffrey Sax bình luận, tôi nhận ra rằng tôi đã chạy trong VS với chế độ Debug.
Sau đó, tôi đã tạo và chạy ở chế độ phát hành, ok, IndexOf
vẫn nhanh hơn nhưng không nhanh hơn nữa.
Dưới đây là kết quả:
Đối với số lượng cặp đôi: 207ms 144ms VS
Đối với đếm một char bình thường: 141ms 111ms VS.
Hiệu suất của mã của riêng tôi đã thực sự được cải thiện.
Bài học kinh nghiệm: khi bạn làm công cụ chuẩn, hãy thực hiện ở chế độ phát hành!
Bạn có bật tối ưu hóa trong khi thử nghiệm không? –
Bạn đã xem xét những gì 'string.IndexOf' đang làm đằng sau hậu trường? – zimdanen
@MartinLiversage Làm cách nào để bật tối ưu hóa? – Jack