C#中for循环和foreach的性能讨论
本人菜鸟大家都发表下自己的观点吧,for循环和foreach在性能上有没有什么区别
------解决方案--------------------一般情况下是忽略不计
1:用户需求(如果要求修改集合内的属性值只能用FOR了,如果只是为了找到对应一批元素,都可以)
2:速度(遍历小集合数据时速度可以忽略,遍历大批量数据尤其是泛型数据时,FOREACH效率更高)
------解决方案--------------------差不多,一个好的实现,for在速度上是不会比foreach慢,foreach功能更强。
foeach是通过"迭代器"来进行循环和取数,类似:
instance !0 valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<int32>::get_Current()
instance bool valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<int32>::MoveNext()
而for是简单的循环,不负责取数,类似:
IL_005f: ldloc.3
[mscorlib]System.Collections.Generic.List`1<int32>::get_Item(int32) //取数
IL_0073: blt.s IL_005f //循环
比较:
1:简循环来说,for不能再省了,但他多一个取count的过程,类似 for (int i=0; i<count; i++)
而迭代器一般是current为空时退出。总的来说for应该占优。
2:取数for不会比foreach差。但这取决与写代码的人。因为for本身不取数。
在本例中是List<int>,那么取取应该是一样。但如果类似int[]数组,那么取数就比迭代器有优秀。
3、这些都是理念上的分析,实际上应该差别不大,但froeach设计较灵活、功能更强大,使得书写的代码简单、优美,同时也可以会少定义几个临时变量。所以个人感觉用foreach会越来越多.
------解决方案--------------------楼主,其实,你不能这么比,循环性能上的差距绝对不是因为你用的是不是 for/foreach 来决定的,如果性能出现问题,一定是 foreach 里面的代码问题。
for 和 foreach,如果要比较的话,我觉得应该比较两者的适用场合。
for 明显更加的灵活,foreach 则只适合简单循环。举个例子:
C# code
for (string s = Console.ReadLine(); s != ""; s = Console.ReadLine())
{
// ......
}
------解决方案--------------------
foreach 适合 对象遍历
for适合变量算法遍历
单纯外部 性能问题??
for(int i = 0; i <a.count; i++)
.count 需要计算
[i] 需要指向!
------解决方案--------------------
测一下不就知道了
C# code
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Press enter to continue testing!");
do
{
For_Each.TestEfficiency();
Console.WriteLine("-------------------------------------------");
} while (Console.ReadKey().Key == ConsoleKey.Enter);
}
static void TestEfficiency()
{
const int COUNT = 100000000;
Stopwatch sw = new Stopwatch();
//改集合类型 ToList()
var list = Enumerable.Range(1, COUNT).ToArray();
int temp = 0;
sw.Start();
for (int i = 0; i < COUNT; ++i) temp = 0 - list[i];
sw.Stop();
Console.WriteLine("for circulate elapsed time:{0}", sw.ElapsedMilliseconds);
temp = 0;
sw.Restart();
foreach (var i in list) temp = 0 - i;
Console.WriteLine("foreach circulate elapsed time:{0}", sw.ElapsedMilliseconds);
}