为什么在读取richtextbox行时foreach比for循环更快

时间:2009-07-16 10:56:52

标签: richtextbox

有两种方法可以逐行从RichTextBox读取数据

1)使用for循环遍历richtextBox

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

2)使用foreach循环枚举richTextBox.Lines集合

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

当我们使用foreach循环枚举richtextbox的数组集合时,性能存在巨大差异。

我尝试了15000行。对于循环需要8分钟才能循环到15000行。而foreach只花了几分钟来枚举它。

为什么会出现这种行为?

5 个答案:

答案 0 :(得分:12)

正如Mehrdad所说,访问Lines属性需要很长时间。你需要在这里小心 - 你现在每次迭代都要访问两次

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

即使您删除循环体中的访问权限,如下所示:

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

仍然在每次迭代时访问Lines,看看你是否已经完成了!

如果您不想foreach,则只需抓取Lines一次:

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

我个人更喜欢foreach,除非您真的需要索引:)

答案 1 :(得分:10)

我认为每次要访问它时都会重新计算Lines属性。因此,foreach方法只执行一次计算,而每次您的引用Lines[i]重新评估整个事物。尝试缓存Lines属性的结果并再次检查:

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

顺便说一句,你的问题隐含假设foreach总是慢于for。这并非总是如此。

答案 2 :(得分:3)

可能是因为找到文本框中的下一行需要时间。在第一种情况下通过索引使用随机访问时,它必须从头开始查找该行。当迭代由foreach在内部完成时,它可以保留状态并快速找到下一行。

这应该使第一种情况在O(n ^ 2)时间内运行,而第二种情况在O(n)中运行。

答案 3 :(得分:0)

是否每个循环中的每一行都被复制到一个新的字符串变量(str)?我在这里不好意思,但你可以用这段代码验证理论

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

答案 4 :(得分:0)

.NET Reflector非常有用,可以确定为什么您会看到您不期望的效果。

尝试查看Lines get访问者,了解每次访问它时实际执行的操作。