2009-07-16 70 views
5

Có hai cách để đọc dữ liệu từ dòng RichTextBox bởi dòngtại sao foreach là nhanh hơn so với vòng lặp for trong khi đọc dòng richtextbox

1) sử dụng một vòng lặp for để lặp qua đường dây của một RichTextBox

String s=String.Empty; 
for(int i=0;i<richtextbox.lines.length;i++) 
{ 
    s=richTextBox.Lines[i] 
} 

2) sử dụng vòng lặp foreach để liệt kê bộ sưu tập richTextBox.Lines

String s=String.Empty; 
    foreach(string str in txtText.Lines) 
    { 
     s=str; 
    } 

Có sự khác biệt lớn về hiệu suất khi chúng tôi sử dụng vòng lặp foreach để liệt kê bộ sưu tập mảng cho richtextbox.

Tôi đã thử với 15000 dòng.cho vòng lặp mất 8 phút để chỉ vòng xuống 15000 dòng. Trong khi đó, foreach mất một phần nhỏ để liệt kê nó.

Tại sao lại có hành vi này?

Trả lời

10

Như Mehrdad đã lưu ý, việc truy cập thuộc tính Lines mất nhiều thời gian. Bạn cần phải cẩn thận ở đây - bạn đang truy cập nó hai lần trong mỗi lần lặp tại thời điểm này:

String s = String.Empty; 
for (int i = 0; i < richTextBox.Lines.Length; i++) 
{ 
    s = richTextBox.Lines[i]; 
} 

Thậm chí nếu bạn loại bỏ các truy cập trong cơ thể của vòng lặp như thế này:

String s = String.Empty; 
for (int i = 0; i < richTextBox.Lines.Length; i++) 
{ 
} 

bạn đang vẫn còn truy cập Lines trên mọi lần lặp lại để xem bạn đã hoàn tất chưa!

Nếu bạn không muốn foreach, bạn chỉ có thể lấy Lines một lần:

string[] lines = richTextBox.Lines; 
for (int i = 0; i < lines.Length; i++) 
{ 
    s = lines[i]; 
} 

Cá nhân tôi thích foreach trừ khi bạn thực sự cần chỉ số mặc dù :)

+0

nếu đó là truy cập hai lần đó là vấn đề thì không nên chỉ mất gấp đôi thời gian. Nhưng sự khác biệt của anh ta là 8 phút so với một phần nhỏ của một giây. – barlop

+1

@barlop: Không, đó không phải là sự khác biệt giữa một hoặc hai lần, đó là sự khác biệt giữa một lần và một lần trên mỗi dòng. –

10

Tôi nghĩ thuộc tính Lines được tính toán lại mỗi lần bạn muốn truy cập. Do đó, phương thức foreach chỉ thực hiện phép tính một lần, trong khi mỗi lần tham chiếu của bạn Lines[i] nó sẽ đánh giá lại toàn bộ sự việc. Hãy thử bộ nhớ đệm kết quả của Lines tài sản và kiểm tra một lần nữa:

String s = String.Empty; 
var lines = richtextbox.Lines; 
for(int i = 0; i < lines.Length; i++) 
{ 
    s = lines[i]; 
} 

Bằng cách này, câu hỏi của bạn làm cho một giả định ngầm rằng foreach luôn là chậm hơn so với for. Điêu nay không phải luc nao cung đung.

+0

nhưng sau đó lý do tại sao nó như vậy nhanh chóng sử dụng foreach. – Rohit

+3

foreach sẽ dịch sang một cuộc gọi đến thuộc tính 'Lines'. Nó gọi 'GetEnumerator()' trên nó và chỉ sử dụng kết quả đếm. Thuộc tính 'Lines' không bao giờ được gọi lại. –

+4

+1 Thuộc tính Lines, được kế thừa từ TextBoxBase, đọc thuộc tính Text và lặp qua nó, ký tự theo ký tự, chia chúng thành các hàng. Gọi là 30k lần (vòng 15k, hai lần để kiểm tra độ dài và giá trị đọc) sẽ chậm hơn gọi nó một lần. – sisve

3

Có lẽ vì việc tìm dòng tiếp theo trong hộp văn bản cần có thời gian. Khi bạn sử dụng truy cập ngẫu nhiên bằng cách lập chỉ mục trong trường hợp đầu tiên, nó phải tìm dòng đó từ đầu. Khi lặp lại được thực hiện trong nội bộ theo foreach, nó có thể giữ trạng thái và nhanh chóng tìm thấy dòng tiếp theo.

Điều này sẽ làm cho trường hợp đầu tiên chạy trong thời gian O (n^2), trong khi lần thứ hai chạy trong O (n).

+0

ngay cả sau khi xóa "s = richTextBox.Lines [i]", nó mất nhiều thời gian. Tôi tự hỏi chỉ cần lặp lại là mất quá nhiều thời gian. – Rohit

+0

Xem câu trả lời của tôi vì sao nó vẫn còn chậm sau khi xóa bỏ dòng đó. –

0

Có thể là mỗi dòng được sao chép vào một biến chuỗi mới (str) trên mỗi vòng lặp? Tôi guissing ở đây, nhưng bạn có thể có thể xác minh lý thuyết này với mã này

String s = String.Empty; 
for (int i = 0; i < richTextBox.Lines.Length; i++) 
{ 
    string str = richTextBox.Lines[i]; 
    s = str; 
} 
+1

Không, đó là không có gì để làm với nó tôi sợ. Việc gán cho biến này hầu như miễn phí. –

0

.NET Reflector là rất hữu ích để xác định tại sao bạn nhìn thấy hiệu suất mà bạn không mong đợi.

Hãy thử xem xét thiết bị truy cập Linesget để xem điều gì thực sự thực hiện mỗi lần bạn truy cập.

Các vấn đề liên quan