Detailed introduction to for vs foreach in c#

黄舟
Release: 2017-02-28 11:44:35
Original
1463 people have browsed it


今天偶然与建议不要用for,可读性太差性能又低,可我个人认为要根据具体情况而定,毕竟for在大部分语言的关键字,可读性不可能因为一个关键字的替代而变好,多数取决于设计和编码习惯。
至于性能,打算写段代码对它们分别测试一下。

var arr = Enumerable.Range(0, 100000000).ToList();
	
	var sw = Stopwatch.StartNew();
	for(var i = 0;i < arr.Count; i++){}
	sw.Stop();
	Console.WriteLine("for loop takes : " + sw.ElapsedTicks);
	
	sw = Stopwatch.StartNew();
	foreach(var x in arr){}
	sw.Stop();
	Console.WriteLine("for loop takes : " + sw.ElapsedTicks);
Copy after login


先看生成的IL

for循环的部分:

...
IL_0018:  ldc.i4.0    
IL_0019:  stloc.2     // i
IL_001A:  br.s        IL_0022
IL_001C:  nop         
IL_001D:  nop         
IL_001E:  ldloc.2     // i
IL_001F:  ldc.i4.1    
IL_0020:  add         
IL_0021:  stloc.2     // i
IL_0022:  ldloc.2     // i
IL_0023:  ldloc.0     // arr
IL_0024:  callvirt    System.Collections.Generic.List<System.Int32>.get_Count
IL_0029:  clt         
IL_002B:  stloc.s     04 // CS$4$0000
IL_002D:  ldloc.s     04 // CS$4$0000
IL_002F:  brtrue.s    IL_001C


...
Copy after login


除了IL_0024中的callvirt会触发方法虚表查询外,几乎不存在任何高消耗的指令。再来看foreach的IL部分:

...
IL_005A:  ldloc.0     // arr
IL_005B:  callvirt    System.Collections.Generic.List<System.Int32>.GetEnumerator
IL_0060:  stloc.s     05 // CS$5$0001
IL_0062:  br.s        IL_006E
IL_0064:  ldloca.s    05 // CS$5$0001
IL_0066:  call        System.Collections.Generic.List<System.Int32>+Enumerator.get_Current
IL_006B:  stloc.3     // x
IL_006C:  nop         
IL_006D:  nop         
IL_006E:  ldloca.s    05 // CS$5$0001
IL_0070:  call        System.Collections.Generic.List<System.Int32>+Enumerator.MoveNext
IL_0075:  stloc.s     04 // CS$4$0000
IL_0077:  ldloc.s     04 // CS$4$0000
IL_0079:  brtrue.s    IL_0064
IL_007B:  leave.s     IL_008C
IL_007D:  ldloca.s    05 // CS$5$0001
IL_007F:  constrained. System.Collections.Generic.List<>.Enumerator
IL_0085:  callvirt    System.IDisposable.Dispose
IL_008A:  nop         
IL_008B:  endfinally  
IL_008C:  nop   
...
Copy after login

首先可以看到很多方法调用,并且在循环体内部每次都要调用方法MoveNext。最后可以看到,有end finally,意味着这个循环外部包了一层try-finally。从IL来看,foreach要比for慢的多了。

现在来看StopWatch的执行结果。

for loop takes : 764538
for loop takes : 1311252
Copy after login

for几乎快了一倍。 

结论:编程语言提供的关键字是为了解决某种问题而存在,需要对具体的业务场景进行判断再决定,有关性能方面,一定要拿出数据说话。  

 以上就是c#, for vs foreach的内容,更多相关内容请关注PHP中文网(www.php.cn)!


Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template