asp.net如何加快页面加载(三)——后台代码之细节2(while,do..while,for,foreach)

上一章节将的是如何使用选择判断语法,今天讲的大家都熟悉的循环语句。我想大家对while,do..while,for,foreach都不陌生吧,但在于性能方面上似乎又觉得陌生? 到底哪个性能更高,效率更快呢。让我们做个测试吧。

     其实在while,do...while,for这三个循环体中效率是一样,为什么会这么说? 其实在执行这三个循环过程中所执行的指令数是一样,只不过执行过程中步骤,内容有细微的不一样。让我们看看下面代码:

        public void Test_While() {
            int n = 10;
            while (n-- > 0) {
                //执行内容
            }
        }

        public void Test_For() {
            for (int n = 10; n > 0; n--) {
                //执行内容
            }
        }

        public void Test_doWhile() {
            int n = 10;
            do {
                //执行内容
            } while (--n > 0);
        }

      小计:从以上代码来上,for语法最近简洁,也最复杂;while语法最简单;do..while执行方式比较特别,先执行内容后判断条件,无论如何至少执行一次以上。在效率方面上while,do..while循环体方法中所执行的指令是一样,而for会比前两种多执行一次。在我们仔细观察看着个多执行一次指令是因为要声明实例化n。那么其实在执行whilehuo do..while之前也是对n先进性实例化。所以三者执行次数是一样,执行效率同时也是一样。至于会影响效率的是执行内容。

       而foreach在效率方面上与前三种有所不同。首先我们先看看foreach工作原理——在foreach循环中,迭代集合collectionObject的过程如下:

  1. 调用collectionObject.GetEnumerator(),返回一个IEnumerator引用。这个方法可以通过IEnumerable接口的实现代码来获得。但这是可选的。
  2. 调用返回的IEnumerator接口的MoveNext()方法。
  3. 如果MoveNext()方法返回true,就使用IEnumerator接口的Current属性获取对象的一个引用,用于foreach循环。
  4. 重复前面两步,直到MoveNext()方法返回false为止,此时循环停止。

接下来我们看看for 与foreach测试:

a.代码部分:

public static void Test_For(string[] inits) {        
            int length = inits.Length;
            string txtfor="";
            for (int i = 0; i < length; i++) {
                //执行内容
                txtfor += inits[i];
            }
        }

        public static void Test_Foreach(string[] inits) {
            string txt = "";
            foreach (string s in inits) {
                txt += s;
            }
        }

        static void Main(string[] args)
        {

            string[] inits = new string[] { "1", "1", "1", "1", "1", "1", "1",
             "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1",
             "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1"};
            Test.CodeTimer.Initialize();
            Test.CodeTimer.Time("一般for循环:", 5, () => { Test_For(inits); });
            Test.CodeTimer.Time("一般foreach循环:", 5, () => { Test_Foreach(inits); });
            Test.CodeTimer.Time("并行for循环:", 5, () =>
            {
                Parallel.For(0, inits.Length, (i) =>
                {
                    Test_For(inits);
                });
            });
            Test.CodeTimer.Time("并行foreach循环:", 5, () =>
            {
                Parallel.ForEach(inits, (i) =>
                {
                    Test_Foreach(inits);
                });
            });
            Console.Read();
            Console.ReadLine();

}

在测试代码计数时间最早使用系统的stopWatch来完成,但考虑到系统的其他程序占用资源,以及该程序的优先级别设置,数据统计等等。最终选择采用老赵设计的CodeTimer来两者之间的比较,当然我们也考虑现有的cpu都是多核多线程,所以我还加入了并行循环的比较, 在计算时间上我做了小改动:watch.ElapsedMilliseconds.ToString("N0") + "ms" 改为 watch.Elapsed,更精确。

  这是结果如下:

asp.net如何加快页面加载(三)——后台代码之细节2(while,do..while,for,foreach)_第1张图片

我们从上述可以得出,在单线程执行foreach会比for占用cpu之原来得大,但在执行效率上有很大的提升。在并行执行中,foreach占尽了各个优势。

那么我们在所有的执行循环体中是不是都把for改成foreach来执行呢? 回答:肯定不是。接下来我们说说哪些情况下使用的for而不是foreach:

1.在片段执行过程使用for,原因是foreach是逐个遍历,至始至终都是从第0位置开始遍历。

2.对循环执行的对象需要更改时使用for,原因foreach遍历过程对象是只读状态,不允许更改对象值。

3.循环的对象不是数组,列表对象使用for,原因foreach只能是集合对象遍历。

总结:选择使用哪个循环语法时,事先考虑是否存在集合对象,对象是否需要遍历,以及代码如何更加简练。



打个自己刚开发的网站广告:生活信息查询平台

 转载请标明原文地址,请大家支持版权。


你可能感兴趣的:(asp.net如何加快页面加载(三)——后台代码之细节2(while,do..while,for,foreach))