下面一段代码,有两个方法,实现的功能是一样的,就是在 arraylist 表里 分别取出一个 string,为了让差别明显些,都循环999999次    private void H()
    {
        string str = "The quick brown fox jumps over a lazy dog";
        ArrayList arrLst = new ArrayList();
        for (int i = 0; i != 9; ++i)
        {
            arrLst.Add(str);
        }
        DateTime timeStart = DateTime.Now;
        int arrLstCnt = arrLst.Count;
        for (int i = 0; i != 999999; ++i)
        {
            for (int j = 0; j != arrLstCnt; ++j)
            {
                object o = arrLst[j];
            }
        }
        DateTime timeEnd = DateTime.Now;
        TimeSpan ts = timeEnd - timeStart;
        this.Title = ts.TotalMilliseconds.ToString();
    }    private void I()
    {
        string str = "The quick brown fox jumps over a lazy dog";
        ArrayList arrLst = new ArrayList();
        for (int i = 0; i != 9; ++i)
        {
            arrLst.Add(str);
        }
        DateTime timeStart = DateTime.Now;
        for (int i = 0; i != 999999; ++i)
        {
            foreach (object obj in arrLst)
            {
                object o = obj;
            }
        }
        DateTime timeEnd = DateTime.Now;
        TimeSpan ts = timeEnd - timeStart;
        this.Title = ts.TotalMilliseconds.ToString();
    }1.我测试表明,用for循环要比foreach遍历要快3倍,我只知道结果是这样,但对于造成这样的结果的准确原因还不知道,请高人解答,谢谢!
2.对于循环条件i != 999999,用 !=(不等号)而不是普通大家用的 <(小于号),这个问题我解决不清楚,因为C++ Primer推荐用的是!=,所以我一直用!=,我记得那书说过原因,但我忘了.

解决方案 »

  1.   

    用!=看着别扭。
    就是砖家说的,那也是C++的砖家,不是C#的。就是C++我也用小于。如果出于某种特殊需要在循环体内改变i的值,有可能变成死循环。
      

  2.   

    QUOTE:如果出于某种特殊需要在循环体内改变i的值,有可能变成死循环。
    ---------------------
    这个是事实,但C++ PRIMER推荐这么写,我就这么写了,而且用久了,习惯了,不愿意去改,嘿嘿.
      

  3.   

    像这种循环应该还看不出来,估计foreach快点
      

  4.   

    测试太不专业!
    测试了几次,每次结果相差多少?
    运行时的环境是怎样的?如果能保证两个运行环境一致?
    是一次运行的还是分别运行的?
    如果是一次运行的,有没有两个顺序颠倒再试?
    有没有改变循环的次数?
    .NET版本?
    操作体统?
    硬件配置?
    结果时间?
    拿具体数据来说话
      

  5.   

    集合对象绝对是foreach快的多,
    具体数字循环,我原来自己小测过一次,差不多的,foreach稍快
      

  6.   

    QUOTE:i               !=               999999
    这种循环条件第一次见,太强大了!
    ----------------
    VMM,你说的是用       !=       而不用       <       是吗,       用       !=       是C++       PRIMER推荐的写法,我也不知道好在哪:)
    =====================================
    假如...i循环到999998时突然变成了1000000...你猜会发生什么事?不要问我为什么会变也不要大叫不可能...in   computer   world...impossible   is   nothing...永远不要猜测计算机的行为...
    我们总是说可以忽略,那就是说有差别,只是差别大小而已.
    当然,在小范围内,那么一点点差别真的是不必要记较的,但在一个项目里,上千上万几十万行的代码,一点点的差别堆积起来就不再是"一点点"了.
    =====================================
    如果项目中需要考虑这种差别...请相信我...我会用C++...优化的重点是拾西瓜而不是去捡芝麻...不要成为穿着长袍而站着喝酒的唯一的人...
      

  7.   

    结帖了就不去看了吗...那个帖子里已经说的很清楚了...IL代码表明:除了变量初始化部分for和foreach循环的执行过程是完全一样的... ps:for和foreach都是迭代语句...遍历什么时候不是循环了?
      

  8.   

    记得看过一篇文章说对foreach是有优化的,能用foreach尽量用。
      

  9.   

    先不说结果有没有问题
    问题是你只测试了arraylist而已,
    就弄"循环与遍历,哪个效率更高"这么大个题目
    不同的东西的遍历当然是不一样的!
    这叫,以偏概全、管中窥豹~
      

  10.   

    关于 != 这个问题,要问C++ PRIMER了,我想作者推荐我们这样用,肯定有他的理由的.
    当然,凡事有两面性,有好也有坏,就象是牺牲效率节省内存和牺牲内存提高效率一样.
      

  11.   

    //关于!=这个问题,要问C++ PRIMER了,我想作者推荐我们这样用,肯定有他的理由的
    他们的理由可能是C++中!=效率高,但是C#可不是C++!.NET更注重的是代码安全性而不是运行效率!
      

  12.   

    QUOTE:他们的理由可能是C++中!=效率高,但是C#可不是C++!.NET更注重的是代码安全性而不是运行效率!
    --------------------------
    难道为了安全而效率完全不要吗?!
      

  13.   

    有人说for快有人说foreach快的原因...我的猜测是:C# 2.0编译器会优化循环体的数据集合而1.x编译器不会...当然我也只是猜猜,因为它们原理上确实是一样的...猜测的依据是MSDN中对迭代器的描述...迭代器是C# 2.0中的新功能。当编译器检测到迭代器时,它将自动生成IEnumerable或IEnumerabe 接口的Current、MoveNext和Dispose方法...
      

  14.   

    我现在理解是这样的:
    foreach (object obj in arrLst) //在这里,每次都是创建一个对象 obj,耗时相对比较大//而在循环中
    object o = arrLst[j];
    //在循环中,看起来是在这个对象集合一个引用而已.
    //所以在这样的情况下,循环for取值要比foreach要效率来得高.
    //我说的都是表面看起来的东西,可能不准我说的都是表面看起来的东西,可能不准
      

  15.   

    QUOTE:你知道什么叫钻牛角尖吗?没有人说完全不要...问题是分清楚重点是什么...如果不知道C#该在哪儿用C++该在哪儿用那不如改学汇编去...这样就可以鄙视一切不用再去跟其他语言比较了...
    -------------------------------
    我想你是对的!
      

  16.   

    for 比 foreach 要高
      

  17.   

    你这个例子与其说在比较for和foreach不如说在比较装拆箱...要优化重点不在for或foreach...给你个例子...
            private static long H()
            {
                string str = "The quick brown fox jumps over a lazy dog";
                List<string> arrLst = new List<string>();
                for (int i = 0; i < 9; i++)
                {
                    arrLst.Add(str);
                }
                DateTime timeStart = DateTime.Now;
                int arrLstCnt = arrLst.Count;
                for (int i = 0; i < 999999; i++)
                {
                    for (int j = 0; j < arrLstCnt; j++)
                    {
                        string o = arrLst[j];
                    }
                }
                DateTime timeEnd = DateTime.Now;
                TimeSpan ts = timeEnd - timeStart;
                return ts.Ticks;
            }        private static long I()
            {
                string str = "The quick brown fox jumps over a lazy dog";
                List<string> arrLst = new List<string>();
                for (int i = 0; i < 9; i++)
                {
                    arrLst.Add(str);
                }
                DateTime timeStart = DateTime.Now;
                for (int i = 0; i < 999999; i++)
                {
                    foreach (string s in arrLst)
                    {
                        string o = s;
                    }
                }
                DateTime timeEnd = DateTime.Now;
                TimeSpan ts = timeEnd - timeStart;
                return ts.Ticks;
            }
      

  18.   

    QUOTE:你这个例子与其说在比较for和foreach不如说在比较装拆箱...要优化重点不在for或foreach...给你个例子... 
    ----------------------
    不好意思,我不太明白,你给了的代码与我的,差别只是在你用泛型的list,我用的是arraylist,这里面差别很大吗?
      

  19.   

    这不是一个泛型那么简单...这是使用强类型避免无谓的装拆箱...装拆箱(boxing & unboxing)对性能的影响远远大于你关注的for & foreach...你不会不知道吧?
      

  20.   

    装拆箱我知道有这概念,但事实真不知道他们所带来的影响,比较原理是什么之类的.
    那么就拿list<string>与arraylist做个比较,不同在哪,好处在哪?
    谢谢!
      

  21.   

    管它谁快谁慢,我已经习惯用foreach了。
      

  22.   

    不完善的测试 private void H()
        {
            string str = "The quick brown fox jumps over a lazy dog";
            ArrayList arrLst = new ArrayList();
            for (int i = 0; i != 9; ++i) // 这里和下面的不等于就不说了
            {
                arrLst.Add(str);
            }
            DateTime timeStart = DateTime.Now;
            int arrLstCnt = arrLst.Count;
            for (int i = 0; i != 999999; ++i)
            {
                for (int j = 0; j != arrLstCnt; ++j)
                {
                    object o = arrLst[j]; //注意这里,取出arrLst的值
                }
            }
            DateTime timeEnd = DateTime.Now;
            TimeSpan ts = timeEnd - timeStart;
            this.Title = ts.TotalMilliseconds.ToString();
        }    private void I()
        {
            string str = "The quick brown fox jumps over a lazy dog";
            ArrayList arrLst = new ArrayList();
            for (int i = 0; i != 9; ++i)
            {
                arrLst.Add(str);
            }
            DateTime timeStart = DateTime.Now;
            for (int i = 0; i != 999999; ++i)
            {
                foreach (object obj in arrLst) //这里已经去出了string
                {
                    object o = obj; //这里又取一次
                }
            }
            DateTime timeEnd = DateTime.Now;
            TimeSpan ts = timeEnd - timeStart;
            this.Title = ts.TotalMilliseconds.ToString();
        }
    一个取值两次,一个一次,你说谁快
      

  23.   

    QUOTE:            foreach (object obj in arrLst) //这里已经去出了string
                {
                    object o = obj; //这里又取一次
                }
    ----------------------foreach总是这么用的呀,取出来,在需要使用地主用上,而for却不必,刚才我在 25楼说了.
      

  24.   

    唔...这里不是装拆箱的问题...string不存在这个问题...看错了...-_-!倦怠 找到关键点了...不过这个例子还是用泛型效率高...因为string虽然没有装拆箱却也有数据类型转换的问题...
      

  25.   

    foreach总是这么用的呀,取出来,在需要使用上,而for却不必,刚才我在   25楼说了.抱歉,手误
      

  26.   

    以上回复没有仔细看
    主要是感觉你的测试代码有问题。for 和 foreach 是用的区别恰在于此, 
    foreach 相当于
    for(...)
     获取数据
      

  27.   

    现在问题又来了,我刚才在将foreach{之里的object o = obj;去掉,但还是跟之前的一样,就是这个foreach耗时还是比for要多三倍左右.}这是为什么,同样是引用一次,foreach效率看起来还是比for要差...
      

  28.   

    代码就象这样    private void H()
        {
            string str = "The quick brown fox jumps over a lazy dog";
            ArrayList arrLst = new ArrayList();
            for (int i = 0; i != 9; ++i)
            {
                arrLst.Add(str);
            }
            DateTime timeStart = DateTime.Now;
            int arrLstCnt = arrLst.Count;
            for (int i = 0; i != 999999; ++i)
            {
                for (int j = 0; j != arrLstCnt; ++j)
                {
                    object o = arrLst[j];
                }
            }
            DateTime timeEnd = DateTime.Now;
            TimeSpan ts = timeEnd - timeStart;
            this.Title = ts.TotalMilliseconds.ToString();
        }    private void I()
        {
            string str = "The quick brown fox jumps over a lazy dog";
            ArrayList arrLst = new ArrayList();
            for (int i = 0; i != 9; ++i)
            {
                arrLst.Add(str);
            }
            DateTime timeStart = DateTime.Now;
            for (int i = 0; i != 999999; ++i)
            {
                foreach (object obj in arrLst)
                {
                }
            }
            DateTime timeEnd = DateTime.Now;
            TimeSpan ts = timeEnd - timeStart;
            this.Title = ts.TotalMilliseconds.ToString();
        }
      

  29.   

    为什么说!=比<效率更高,
    在汇编里小于跳转和不等于跳转分别是glt,gn,(没记错的话)这两个最底层命令的效率差别能有多少?
      

  30.   

    For迭代:
    调用的是System.Collections.ArrayList::get_Item(int32)Foreach迭代调用了:
    System.Collections.ArrayList::GetEnumerator()
    System.Collections.IEnumerator::get_Current()
    System.Collections.IEnumerator::MoveNext()
    System.IDisposable::Dispose()
    而且代码中包含一对try{}finally{}块另外:foreach块中的代码可能不会执行,因为编译器并不编译里面的代码,
    原因如下:object o始终未被引用,编译器会将它忽视
    这一点可以通过查看汇编代码来证明
      

  31.   

    1、少一次反射,就有999999次foreach的性能了
    2、List<T>的迭代器是值类型(foreach不会去装箱),而ArrayList的迭代器是引用类型,所以ArrayList的Foreach需要额外分配999999次对象,而List<T>不需要
    3、如果换成Hashtable或Dictionary<TKey,TValue>,再比较一下看看
      

  32.   

    一维数组for快,编译器有优化.
    集合应该是foreach快.
      

  33.   

    我知道ms为什么说foreach比for要快了按它的理论getItem(int i )
    那么取 0 索引的按寻址运算,姑且认为是指针在移
    索引 0
    从null移到0 
    取1索引
    指针要移二次
      null ->0 ->1
    取 3索引
    null->0 ->1 -> 2
    那么我们用for,这僦是个阶加的运算
    1+ 2 +3 +..+ n
    如果用foreach
    那么
    移动次数就是n
    还不如去学c++
    妈的,至少看起来是那回事
      

  34.   

    在实现相同功能的情况下,foreach 一定比 for 慢,
    原因是 foreach 需要额外的方法 MoveNext() 和属性调用Current、以及类型转换。
    下列形式的 foreach 语句:
    foreach (ElementType element in collection) statement
    对应于两个可能的扩展中的一个:
    1:如果 collection 表达式的类型实现了集合模式(如上面定义的那样),则 foreach 语句的扩展是:E enumerator = (collection).GetEnumerator();
    try {
       ElementType element;
    while (enumerator.MoveNext()) {
    element = (ElementType)enumerator.Current;
    statement;
    }
    }
    finally {
    IDisposable disposable = enumerator as System.IDisposable;
    if (disposable != null) disposable.Dispose();
    }通常可以很容易对上述代码进行有效的优化。如果类型 E 实现了 System.IDisposable,则表达式 (enumerator as System.IDisposable) 将始终为非 null,因而,该实现可以安全地用一个简单转换替代可能更昂贵的类型测试。相反,如果类型 E 是 sealed 而且没有实现 System.IDisposable,则表达式 (enumerator as System.IDisposable) 的计算结果始终为 null。这种情况下,在上述代码中可以安全地删除整个 finally 子句。
    2:否则,collection 表达式的类型就实现了 System.IEnumerable,这样,foreach 语句的扩展就成为:IEnumerator enumerator = 
               ((System.Collections.IEnumerable)(collection)).GetEnumerator();
    try {
       ElementType element;
    while (enumerator.MoveNext()) {
    element = (ElementType)enumerator.Current;
    statement;
    }
    }
    finally {
    IDisposable disposable = enumerator as System.IDisposable;
    if (disposable != null) disposable.Dispose();
    }在上面两个扩展的任意一个中,enumerator 变量是一个临时变量,它在嵌入 statement 中既是不可访问的,也是不可见的,element 变量在嵌入 statement 中是只读的。不管如何优化,GetEnumerator()、MoveNext()、Current 调用是无法缺少的,而对于 MoveNext()、Current 与 for 中的计数器,索引访问是一样的。下面以对 String 对象的 for 和 foreach 为例,都实现将字符串中的所有字符访问一次的功能:首先看 for 语句:int len = str.Length;
    for (int j = 0; j != len; ++j)
    {
    char s = str[j]; 
    }就是这么简洁,没有额外的操作。再看 foreach 语句:foreach (char c in str)
    {
    char s = c;
    }从代码上来看,foreach 更简洁、优美,
    但是,foreach 展开之后,类似于:IEnumerator etor = str.GetEnumerator();
    while (etor.MoveNext())
    {
    char c = (char)etor.Current; // 这里还有装箱和拆箱的性能损耗
    }展开为类似于 for 的形式:int length = str.Length;for (int i = 0; i < length; i++)
    {
    etor.MoveNext();
    char c = (char)etor.Current; // char c = string[i];
    }不难看出比上面的 for 多做了些什么,当然编译器不是这么展开的,但运行次数是差不多的。string 的 GetEnumerator 方法将创建一个 CharEnumerator 类型的对象;
    CharEnumerator 的定义为:[Serializable, ComVisible(true)]
    public sealed class CharEnumerator : ICloneable, IEnumerator<char>, IDisposable, IEnumerator
    {
        // Fields
        private char currentElement;
        private int index;
        private string str;    // Methods
        internal CharEnumerator(string str)
        {
            this.str = str;
            this.index = -1;
        }    public object Clone()
        {
            return base.MemberwiseClone();
        }    public bool MoveNext() // 看看 MoveNext, 代码还不少呢
        {
            if (this.index < (this.str.Length - 1))
            {
                this.index++;
                this.currentElement = this.str[this.index];
                return true;
            }
            this.index = this.str.Length;
            return false;
        }    public void Reset()
        {
            this.currentElement = '\0';
            this.index = -1;
        }    void IDisposable.Dispose()
        {
        }    // Properties
        public char Current
        {
            get
            {
                if (this.index == -1)
                {
                    throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumNotStarted"));
                }
                if (this.index >= this.str.Length)
                {
                    throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumEnded"));
                }
                return this.currentElement;
            }
        }    object IEnumerator.Current // 这里要装箱,赋值(char c = (char)etor.Current)的时候还要拆箱
        {
            get
            {
                if (this.index == -1)
                {
                    throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumNotStarted"));
                }
                if (this.index >= this.str.Length)
                {
                    throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumEnded"));
                }
                return this.currentElement;
            }
        }
    }这就是 foreach 一定慢的原因。
      

  35.   

    理论说完了,用事实说话,测试谁快:// with Releaseusing System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Text;namespace TempTestA1
    {
        public class Class2
        {        static long F()
            {
                string str = "The quick brown fox jumps over a lazy dog";
                DateTime timeStart = DateTime.Now;
                for (int i = 0; i != 999999; ++i)
                {
                    for (int j = 0; j != str.Length; ++j)
                    {
                        char s = str[j];
                    }
                }
                DateTime timeEnd = DateTime.Now;
                TimeSpan ts = timeEnd - timeStart;
                return ts.Ticks;
            }        static long G()
            {
                string str = "The quick brown fox jumps over a lazy dog";
                DateTime timeStart = DateTime.Now;
                for (int i = 0; i != 999999; ++i)
                {
                    foreach (char c in str)
                    {
                        char s = c;
                    }
                }
                DateTime timeEnd = DateTime.Now;
                TimeSpan ts = timeEnd - timeStart;
                return ts.Ticks;
            }        static void Main(string[] args)
            {
                int b = 0;            b++; // 设置断点            int fcount = 0/* f 快的次数 */, gcount = 0/* g 快的次数 */, eq = 0/* 一样快的次数 */;            for (int i = 0; i < 20; i++) // 第 1 段
                {
                    long f = F();                long g = G();                if (f < g) fcount++; else if (f != g) gcount++; else eq++;            }            for (int i = 0; i < 20; i++) // 第 2 段
                {
                    long g = G();                long f = F();                if (f < g) fcount++; else if (f != g) gcount++; else eq++;            }            b++; // 设置断点        }
        }
    }// 测试结果:
    /*times 1, 使用第 1 段(注释第 2 段):
        fcount    18    int
        gcount    0    int
        eq    2    inttimes 2, 使用第 1 段(注释第 2 段):
        fcount    20    int
        gcount    0    int
        eq    0    inttimes 3, 使用第 1 段(注释第 2 段):
        fcount    20    int
        gcount    0    int
        eq    0    inttimes 4 使用第 1 段(注释第 2 段):
        fcount    20    int
        gcount    0    int
        eq    0    inttimes 5, 使用第 1 段(注释第 2 段):
        fcount    19    int
        gcount    0    int
        eq    1    inttimes 6, 使用第 2 段(注释第 1 段):
        fcount    20    int
        gcount    0    int
        eq    0    inttimes 7 使用第 2 段(注释第 1 段):
        fcount    19    int
        gcount    0    int
        eq    1    inttimes 8, 使用第 2 段(注释第 1 段):
        fcount    20    int
        gcount    0    int
        eq    0    inttimes 9, 使用第 2 段(注释第 1 段):
        fcount    20    int
        gcount    0    int
        eq    0    inttimes 10, 使用第 2 段(注释第 1 段):
        fcount    20    int
        gcount    0    int
        eq    0    inttimes 11, 第 1 和 2 段一起(都不注释):
        fcount    40    int
        gcount    0    int
        eq    0    inttimes 12, 第 1 和 2 段一起(都不注释):
        fcount    40    int
        gcount    0    int
        eq    0    inttimes 13, 第 1 和 2 段一起(都不注释):
        fcount    40    int
        gcount    0    int
        eq    0    inttimes 14, 第 1 和 2 段一起(都不注释):
        fcount    40    int
        gcount    0    int
        eq    0    inttimes 14, 第 1 和 2 段一起(都不注释):
        fcount    40    int
        gcount    0    int
        eq    0    int*/
      

  36.   

    到底有多快?再测试一下:// with Releaseusing System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Text;namespace TempTestA1
    {
        public class Class3
        {        static long F()
            {
                string str = "The quick brown fox jumps over a lazy dog";
                DateTime timeStart = DateTime.Now;
                for (int i = 0; i != 999999; ++i)
                {
                    for (int j = 0; j != str.Length; ++j)
                    {
                        char s = str[j];
                    }
                }
                DateTime timeEnd = DateTime.Now;
                TimeSpan ts = timeEnd - timeStart;
                return ts.Ticks;
            }        static long G()
            {
                string str = "The quick brown fox jumps over a lazy dog";
                DateTime timeStart = DateTime.Now;
                for (int i = 0; i != 999999; ++i)
                {
                    foreach (char c in str)
                    {
                        char s = c;
                    }
                }
                DateTime timeEnd = DateTime.Now;
                TimeSpan ts = timeEnd - timeStart;
                return ts.Ticks;
            }        static void Main(string[] args)
            {
                int b = 0;            b++; // 设置断点            long fcount = 0/* f 用时 */, gcount = 0/* g 用时 */;            for (int i = 0; i < 20; i++) // 第 1 段
                {
                    fcount += F();                gcount += G();            }            for (int i = 0; i < 20; i++) // 第 2 段
                {
                    gcount += G();                gcount += F();            }            b++; // 设置断点        }
        }
    }// 测试结果
    /*
    times 1, 第 1 和 2 段一起(都不注释):
        fcount    15156250    long
        gcount    57812500    longtimes 2, 第 1 和 2 段一起(都不注释):
        fcount    15625000    long
        gcount    56406250    longtimes 3, 第 1 和 2 段一起(都不注释):
        fcount    14843750    long
        gcount    57812500    longtimes 4, 第 1 和 2 段一起(都不注释):
        fcount    15468750    long
        gcount    57031250    longtimes 5, 第 1 和 2 段一起(都不注释):
        fcount    15468750    long
        gcount    56562500    long*/
      

  37.   

    第 2 个问题,效率是一样的,一个是 je, 一个是 jge,都是一条汇编指令,
    如下所示:
    int a = 0,  i = 0;
    00415BA7  mov         dword ptr [a],0 
    00415BAE  mov         dword ptr [i],0 
    if(a<1)i++;
    00415BB5  cmp         dword ptr [a],1 // 比较
    00415BB9  jge         main+64h (415BC4h) // 大于或等于则跳转
    00415BBB  mov         eax,dword ptr [i] 
    00415BBE  add         eax,1 
    00415BC1  mov         dword ptr [i],eax 
    if(a!=1)i++;
    00415BC4  cmp         dword ptr [a],1 // 比较
    00415BC8  je          main+73h (415BD3h) // 等于则跳转
    00415BCA  mov         eax,dword ptr [i] 
    00415BCD  add         eax,1 
    00415BD0  mov         dword ptr [i],eax  i++;
    00415BD3  mov         eax,dword ptr [i] 
    00415BD6  add         eax,1 
    00415BD9  mov         dword ptr [i],eax 
      

  38.   

    自己看看foreach是怎么实现的吧,我认为for要快些
      

  39.   

    天呀,当然是for快了,for原生方法,foreach也是for的呀
      

  40.   

    楼主应该说:foreach与for哪个更快。“循环”与“遍历”根本不是一个层面的概念。下面短语示例:
    循环遍历、递归遍历、随机遍历(遍历无约定次序,然后每次把遍历过的排出去。呵呵。)(不过与主题思想没什么关系,纯属灌水)
      

  41.   

    留个名 据说foreach安全,但我还是一直用for...  估计循环个100w次就很明显了
      

  42.   

     一般我还是用foreach,不过也要看具体的情况。
      

  43.   

    如此经典的回复..留名.喜欢用foreach不过感觉for更底层应该更快.但是光靠感觉还是不行D...
      

  44.   

    当然for ,wihle 等要快于foreach因为后者封装了前者
      

  45.   

    foreach是集合操作,因为.NET中任何[]都是集合(当然还有链表,树啊这些)
    ,而集合的特定循环foreach封装了wihle或for等语句,所以其实是一回事,
    但效率上由于多封装了一层所以会有一定成本,但这种成本是值得的,不然MS也
    不会多事,搞个foreach出来.
      

  46.   

    foreach的本质还是for,foreach增加的复杂度是常数。
    复杂度是n的情况下,由加一个常数引起的边界成本可以忽略。
    还记得复杂度理论里说的吗?O(n)+k=O(n)
    当嵌套循环的时候
    (O(n)+k)*(O(m)+l)边界成本会升高,但是理论上还是O(m*n)理论上证明,foreach增加的边界成本不会从根本上影响复杂度,但会略微增加运行时间。
    如果测试结果差距3倍,也不能说明foreach过于效率低,
    因为这个三倍是加法引起的,不是出现积数,对数,指数的情况。
      

  47.   

    c++的iterator是指针移动, 所以性能高.. C#显然应该是for快些. 没有多余的函数调用
      

  48.   

    我也觉得Foreach应该牵扯到装拆箱的问题
    所以会比for要慢