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

Roh*_*nsi 5 richtextbox

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

1)使用for循环遍历richtextBox的行

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

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

   String s=String.Empty;
   foreach(string str in txtText.Lines)
    {
       s=str;
    }
Run Code Online (Sandbox Code Playgroud)

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

我尝试了15000行.for循环需要8分钟才能循环到15000行.而foreach只花了一秒钟来枚举它.

为什么会出现这种行为?

Jon*_*eet 13

正如Mehrdad所说,进入该Lines物业需要很长时间.你需要在这里小心 - 你现在每次迭代都要访问它两次:

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

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

String s = String.Empty;
for (int i = 0; i < richTextBox.Lines.Length; i++)
{
}
Run Code Online (Sandbox Code Playgroud)

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

如果你不想foreach,你可以只获取Lines一次:

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

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


Meh*_*ari 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];
}
Run Code Online (Sandbox Code Playgroud)

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

  • +1从TextBoxBase继承的Lines属性读取Text属性并逐个字符地循环它,以将它们分成行.调用30k次(15k循环,两次检查长度和读取值)将比调用一次慢. (4认同)
  • foreach将转换为对"Lines"属性的单个调用.它在其上调用`GetEnumerator()`并仅使用生成的枚举器.`Lines`属性永远不会被再次调用. (3认同)