schumyxp的专栏

编程是一门艺术

用户操作
[即时聊天] [发私信] [加为好友]
卢一鸣ID:schumyxp
16883次访问,排名7065(-2)好友12人,关注者12
如果你无所不能,那就来当一名程序员吧!
schumyxp的文章
原创 83 篇
翻译 0 篇
转载 2 篇
评论 20 篇
最近评论
hdnero:wow power leveling
hdnero:wow power leveling
java_lover_:专业,经典,学习就是要到这种境界,顶顶....
bigdog202:著名外资公司windows/c++的机会,感兴趣与我联系MSN:zhang_dave@hotmail.com
mixianger:厉害!考虑问题的角度.....学习下。
文章分类
收藏
    相册
    .net
    .Net源码 - Asp.Net Forums
    Apache log4net - Apache log4net: Home
    ASP.NET AJAX 中文站
    BCL Team Blog
    CodePlex - Open Source Project Hosting
    Guido van Rossum 博客中文版
    Hawkeye - The .Net Runtime Object Editor
    heker2007的专栏 - LINQ to SQL系列
    Kiwidude's Geek Spot - NCoverExplorer Downloads
    LINQ Project General - MSDN Forums
    Lutz Roeder's Programming.NET C# VB CLR
    MSDN Forums
    MSDN 主页 (中国 - 简体中文)MSDN 主页 (中国 - 简体中文)
    MSDN2 Library
    MSFN - Where People Go To Know
    NCover - Code Coverage for .NET Developers
    NUnit - Home
    Reporting Services 入门
    Scott Guthrie 博客中文版
    Scott Mitchell的ASP.NET2.0数据指南中文版索引
    ScottGu's Blog
    SQL Server 2005 Books Online Scoped Search
    The Official Microsoft ASP.NET Site
    Visual C++, .Net, C#, C++, Win32, Programming resources - CoderSource.net
    一个下载电子书的超级网站
    c/c++
    Boost C++ Libraries
    Center of STL Study--最优秀的STL使用学习网站
    cplusplus.com - The C++ Resources Network
    Herb Sutter 博客中文版
    D语言
    Digital Mars C, C++ and D Compilers
    Intro - D Programming Language 2.0 - Digital Mars
    emacs
    Aquamacs: Emacs for Mac OS X
    Collection of Emacs Development Environment Tools Homepage
    ECB - Emacs Code Browser
    Emacs - Main - HomePage
    Emacs 中文化指南
    EmacsWiki: 網站地圖
    GNU Emacs - GNU Project - Free Software Foundation (FSF)
    SourceForge.net: EMHACKS
    Template Package for Emacs
    一个暴好的Emacs中文站点
    linux
    ChinaUnix.net = 全球最大的 Linux Unix 中文网站 = IT人的网上家园
    Eclipse.org home
    freshmeat.net: Welcome to freshmeat.net
    GCC, the GNU Compiler Collection - GNU Project - Free Software Foundation (FSF)
    GNU Make - GNU Project - Free Software Foundation (FSF)
    linux C
    Linux Howtos: Home
    Linux中国 | Linux中国门户站!
    Linux中国下载站
    sidux.com :: debian based live cd development
    The Linux Kernel Archives
    python
    IronPython - Home
    Phillip J.Eby 博客中文版
    Python Programming Language -- Official Website
    深入 Python :Dive Into Python 中文版
    简明 Python 教程
    好站推荐
    .NET-UML软件工程组织
    CodeProject. Free source code and programming help
    Google Code Search
    IT公司速查手册-IT人士求职参考
    Martin Fowler's Bliki 中文版
    SourceForge.net: Welcome to SourceForge.net
    SourceMonitor Version 2.4
    语言工具
    存档
    订阅我的博客
    XML聚合  FeedSky
    订阅到鲜果
    订阅到Google
    订阅到抓虾
    订阅到BlogLines
    订阅到Yahoo
    订阅到GouGou
    订阅到飞鸽
    订阅到Rojo
    订阅到newsgator
    订阅到netvibes

    原创 for循环嵌套的效率收藏

    新一篇: makefile第二版发布了 | 旧一篇: 五一归来

    有人说,两个嵌套的for循环,把循环次数多的放在里面,效率会比较高。

    这是个老话题了。网上的讨论很多。我记得我第一次见到这个问题的时候还在上高中。今天就简单的总结一下吧。

    先上代码:
    void test1()
    {
     long dt = DateTime.Now.Ticks;
     for (int i = 0; i < 1000000; i++)
     {
      for (int j = 0; j < 10; j++)
      {
       a[i,j] = 0;
      }
     }
     Console.WriteLine("test1:{0}",DateTime.Now.Ticks - dt);
    }

    void test2()
    {
     long dt = DateTime.Now.Ticks;
     for (int j = 0; j < 10; j++)
     {
      for (int i = 0; i < 1000000; i++)
      {
       a[i,j] = 0;
      }
     }
     Console.WriteLine("test2:{0}",DateTime.Now.Ticks - dt); 
    }

    有书上说是方法2快,道理是大的循环放在里面,效率会比较高。

    不过实际的结果,一般都是方法1快,而且快很多。这是为什么呢?
    这是因为当CPU从内存获取数据到cache的时候,是一块一块获取的。因此,如果我们的程序总是顺序的访问内存,那么cache的利用率就会比较高了,会大大减少系统换页的次数,提高程序运行的效率。

    对于多维数组,每行的最后一个数据后面,紧接着的是下一行的第一个。因此,方法1是顺序访问内存,方法2则是跳跃性的访问内存。这样一来,谁快谁慢自然就很明了了。

    不过,并不能因此就说书上说错了,更不能说把大的循环放在外面才会更高效。

    再看下面的代码:
    void test3()
    {
     long k = 0;
     long dt = DateTime.Now.Ticks;
     for (int i = 0; i < 1000000; i++)
     {
      for (int j = 0; j < 10; j++)
      {
       k++;
       if (k > 100000)
        k++;
      }
     }
     Console.WriteLine("test3:{0}",DateTime.Now.Ticks - dt); 
    }

    void test4()
    {
     long k = 0;
     long dt = DateTime.Now.Ticks;
     for (int j = 0; j < 10; j++)
     {
      for (int i = 0; i < 1000000; i++)
      {
       k++;
       if (k > 100000)
        k++;
      }
     }
     Console.WriteLine("test4:{0}",DateTime.Now.Ticks - dt); 
    }

    实际的测试结果支持了大循环在内部会快一些的说法,虽然快的幅度很有限吧。

    出现这个问题的原因,在于CPU的流水线长度和预判断功能的强弱。如果CPU流水线长,而预判定功能又很准确,那方法4的效率将超过方法3很多。如果流水线很长,但是预判定功能不好,方法4就不一定比方法3快了,甚至还会慢很多。

    比如高频率的P3 CPU,流水线短,分支预判功能效果好,在上面测试方法3和方法4就区别不大。再比如低频率的P4 CPU,流水线很长,但是预判定效果差,方法4在这上面就会吃大亏。

    所以,把大的循环放在最里面,并不是永恒不变的硬道理。究竟要如何取舍,还得根据实际的硬件情况和软件逻辑来做选择。更好的方法就是,选择一个合适的设计结构,避免陷入上面的问题。唯一的真理就是:实际测试一下,用事实说话。

    附:测试结果:
    方法:时间(tick)
    test1:2187500
    test1:1875000
    test1:1718750
    test1:1718750
    test1:1718750
    test2:4375000
    test2:4375000
    test2:4218750
    test2:4375000
    test2:4375000
    test3:1562500
    test3:1406250
    test3:1562500
    test3:1406250
    test3:1562500
    test4:1093750
    test4:1250000
    test4:1406250
    test4:1250000
    test4:1250000

    发表于 @ 2008年05月06日 09:41:14|评论(loading...)|编辑

    新一篇: makefile第二版发布了 | 旧一篇: 五一归来

    评论

    #mixianger 发表于2008-06-12 10:54:21  IP: 218.25.117.*
    厉害!考虑问题的角度.....学习下。
    #java_lover_ 发表于2008-06-14 10:04:16  IP: 218.57.175.*
    专业,经典,学习就是要到这种境界,顶顶....
    发表评论  


    登录
    Csdn Blog version 3.1a
    Copyright © 卢一鸣