zoukankan      html  css  js  c++  java
  • 正确的优化分段函数形式的多重分支代码

    File:      fastmif.txt
    Name:      正确的优化分段函数形式的多重分支代码
    Author:    zyl910
    Blog:      http://blog.csdn.net/zyl910/
    Version:   V1.00
    Updata:    2006-10-13


    一、基本代码
      有时候,我们会碰上这样的多重分支代码:
    char szbuf[10];
    if     (score >= 90) strcpy(szbuf, "优");
    elseif (score >= 80) strcpy(szbuf, "良");
    elseif (score >= 60) strcpy(szbuf, "及格");
    else                 strcpy(szbuf, "不及格");

      这样的代码无疑是很低效的,怎么优化呢?


    二、错误的优化

      很多书上说可以根据频率分布来优化代码,比如及格的人最多时,这样编写代码:
    char szbuf[10];
    if     (score >= 60 && score < 80) strcpy(szbuf, "及格");
    elseif (score >= 80 && score < 90) strcpy(szbuf, "良");
    elseif (score >= 90)               strcpy(szbuf, "优");
    else                               strcpy(szbuf, "不及格");

      可以看出,这样做实际上增加了判断次数。只有在分支极多时,该优化方案才比上一个好。


    三、正确的优化

      现在都是做整数比较,速度非常快的,反而会因判断之后的跳转指令堵塞流水线而影响效率。所以正确的优化代码应该是这样的:
    const char szlist[][10] = {"不及格", "及格", "良", "优"};
    char szbuf[10];
    int i=0;
    i += ( score >= 60 ); // #1
    i += ( score >= 80 ); // #2
    i += ( score >= 90 ); // #3
    strcpy(szbuf, szlist[i]);

      当score小于60时,#1、#2、#3均不成立,所以 i = i + 0 + 0 + 0 = i + 0 = 0
      当score在[60,80)区间时,#1成立,所以 i = i + 1 + 0 + 0 = i + 1 = 1
      当score在[80,90)区间时,#1、#2均成立,所以 i = i + 1 + 1 + 0 = i + 2 = 2
      当score大于90时,#1、#2、#3均成立,所以 i = i + 1 + 1 + 1 = i + 3 = 3
      最后用索引i从szlist中得到具体数据。


    四、全面优化

      看出来了吧,对于这种分段函数形式的多重分支代码,可以根据数据特点来优化。所以,我们还可以更进一步,将程序改成表格驱动的形式:
    const char szlist[][10] = {"不及格", "及格", "良", "优"};
    const char idxlist[] = {60, 80, 90};

      然后我们在idxlist表中搜索score,得到索引,再用索引从szlist得到数据。
      这样无论以后的需求如何改变,我们只需要修改这两行代码就行了。

      这时,可能会有人问了:如果分支极多怎么办,难道还是一个一个的比较?现在流行面向对象编程,很多时候进行的是对象比较,而对象比较的速度很慢,而现在又搞这么多比较,那不是影响效率吗?

      注意我刚才说过什么——“在idxlist表中搜索score”,现在idxlist中的数据是有序的,当然用二分法查找啊!
      具体说起来,由于我们在小于60(idxlist[0])时返回0、在大于等于60(idxlist[0])且小于80(idxlist[1])时返回1……所以这实际上是一个插入到有序容器算法,只不过我们只需得到插入位置(索引),并不需要进行插入。


    五、总结

      对于“一、基本代码”,其平均判断次数是 n/2,即 O(n)。
      对于“三、正确的优化”,其平均判断次数是 n-1,即 O(n)。运算复杂度与上一个一样,但是由于它避免了跳转,所以在项目较少时,该代码的效率最高。
      对于“四、全面优化”,由于它采用了二分法查找,其运算复杂度为 O(logn)。在项目很多时,它的效率最高。
     

    作者:zyl910
    版权声明:自由转载-非商用-非衍生-保持署名 | Creative Commons BY-NC-ND 3.0.
  • 相关阅读:
    wcf通道Channel
    固定位置右下角
    小闹钟(无样式)
    CSS小注意(初级)
    java少包汇总
    maven的pom.xml配置
    myeclipse 手动安装 lombok
    Could not synchronize database state with session
    (转)myeclipse插件—SVN分支与合并详解【图】
    Nginx的启动、停止与重启
  • 原文地址:https://www.cnblogs.com/zyl910/p/2186636.html
Copyright © 2011-2022 走看看