• 代码优化向导第一部分


        这是一篇在网上看到的技术文章,它把一个原来需要6000毫秒的代码段优化到400毫秒,这种优化效果让我震撼,所以我决定把它翻译共享出来。

        下面是原文链接:http://www.codeproject.com/Articles/381630/Code-optimization-tutorial-Part-1

    简介:

        这篇文章是尝试把代码优化技术介绍给软件开发者。为些,我们将探究各种优化的方法。
        第一步,我选取一段容易理解的算法代码段,并在上面运用各种不同的优化方法。
        我们要解决的问题是3n+1猜想(关于这个问题的详细解释大家可以点这个链接 3n+1问题详细),
        我们执行一个从1到1000000的循环,每个数都套用这个函数:
        
        直到n变成1,我们再执行下一个数,我们不需要从键盘上读取任何数据程序就可以打印结果,并且我们可以计算出运行的时间,用来做测试的设备是:   AMD Athlon 2 P340 Dual Core 2.20 GHz, 4 GB of RAM, Windows 7 Ultimate x64。测试的语言是:C#和C++
        代码的第一个版本:为1到1000000中的每个数执行上面的算法,算法会产生一系列的数字,直到等于1时才会停止,归1的步骤数将会被记录下来,并且最大的步骤数将会被确定下来。
    C++代码段:
    for (int i = nFirstNumber; i < nSecondNumber; ++i)
    {
        int nCurrentCycleCount = 1;
        long long nNumberToTest = i;
        while (nNumberToTest != 1)
        {
            if ((nNumberToTest % 2) == 1)
            {
                nNumberToTest = nNumberToTest * 3 + 1;
            }
            else
            {
                nNumberToTest = nNumberToTest / 2;
            }
            nCurrentCycleCount++;
        }
        if (nCurrentCycleCount > nMaxCycleCount)
        {
            nMaxCycleCount = nCurrentCycleCount;
        } 
    }  
    C#代码段:
    for (int i = FirstNumber; i < SecondNumber; ++i)
    {
        int iCurrentCycleCount = 1;
        long iNumberToTest = i;
        while (iNumberToTest != 1)
        {
            if ((iNumberToTest % 2) == 1)
            {
                iNumberToTest = iNumberToTest * 3 + 1;
            }
            else
            {
                iNumberToTest = iNumberToTest / 2;
            }
            iCurrentCycleCount++;
        }
        if (iCurrentCycleCount > MaxCycleCount)
        {
            MaxCycleCount = iCurrentCycleCount;
        }
    } 

        我用Debug和Release模式以及32位和64位分别执行了这段代码,然后我每次都运行100次取平均值(单位是ms)。下面是运行的结果:
      C++ Debug C++ Release C#Debug C# Release
    x86 version 6882 6374 6358 5109
    x64  versiong 1020 812 1890 742

        我们从表里面看到的第一点是,32位的程序要比64位的慢5到7倍,因为x64设计是一个寄存器可以存储一个long long数据,而x86而需要两个寄存器,所以在后面我们不再研究32位的程序。第二点是,Debug和Release所用的时间差距很大,特别是C#。第三点是,通过观察,C#编译器貌似比C++编译器在优化方面更胜一筹。
    我提供的第一个优化动作是与数学操作符有关的,我用非传统的方式替换传统的方式。我们可以看到上面的代码里面只有三个复杂的数学操作符:%,*,/。首先我要优化的是%2操作,我们发现只要与0x1做&操作就可以判断一个数是否是奇数。所以当我们执行下面的替换时:
    if ((nNumberToTest % 2) == 1)
    替换成:
    if ((nNumberToTest & 0x1) == 1)
    下面是新的结果表:
    C++ Debug C++ Release C# Debug C# Relase
    922 560 1641 714

        我们发现,C++ Release版本得到了很大的优化,Release和Debug版本的优化程序不同让我相信,在Release版本下编译器会删除多余的指令。C#则好像没有太大的优化。下一个优化的动作是/2操作,我们发现用位操作>>1与/2操作得到的是相同的效果, 所以当我们执行下面的替换时
    nNumberToTest = nNumberToTest / 2;
    替换成:
    nNumberToTest = nNumberToTest >> 1;
    下面是新的结果:
    C++ Debug C++ Release C# Debug C# Relase
    821 555 1432 652
        我们发现C++ Debug, C# Debug, C# Release有差不多65到200毫秒的优化,而C++ Release版本则好像没有优化一样,那是因为在这种模式下编译器已经做了这个转换操作。最我们能做的变换只能是把*换成+操作, 所以当我们执行下面的替换时
    nNumberToTest = nNumberToTest * 3 + 1; 
    替换成:
    nNumberToTest = nNumberToTest + nNumberToTest + nNumberToTest + 1; 
    下面是新的结果:

    C++ Debug C++ Release C# Debug C# Relase
    820 548 1535 629
  • 相关阅读:
    listview删除item
    标准listview加图标布局
    android事件消费机制,从外传到里面,里面具有优先选择权,如果里面的不需要,则传递给外面一层消费
    listview 按最新数据展示
    给listview添加数据,添加数据之后即刻显示出来,并把数据放在listview列表的最前面
    EditText限制输入长度和限定输入数字
    josn解析常见的几种方法
    bnu Robots on a grid
    hdu 1348 Wall
    hdu poj Oulipo
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3093464.html
Copyright © 2020-2023  润新知