代码级的性能优化(一)

       对于性能的优化, Jon Bentley告诉我要分5个步骤:

       1) 算法和数据结构的选择
       2) 算法的优化
       3) 数据结构的重组
       4) 代码优化
       5) 提升硬件性能

        我想谈谈关于代码优化的问题.

        我们知道java中StringBuffer 和 String的区别, 在处理散列时要用HashMap来代替HashTable, 对于输入/输入流的处理尽量尝试使用Reader/Writer...
        一个追求速度的程序员会将优化的代码体现在他的每一段程序上, 以下是几个程序片段:


       1) 乘/除法如果使用位运算要比"*" 和 "/" 快一些
           result = 4 * 15 的等价代码:
           result = 4 << 4 - 1        (15 = 2 * 2 * 2 * 2 - 1)

       2) 循环和减法要比直接使用求模运算符获得更好的性能
          a % b 的等价代码:
          while(a >= b)
              a -= b;  

       3) 对于交换两个数a,b, 位运算比声明中间变量更快
            int temp = a;
           a = b;
           b = temp;
          等价代码:
          a = a ^ b;
          b = b ^ a;
          a = a ^ b;

      4) 如果代码在连续的内存块中, 将获得更好的性能
        if(result != null)
            do something useful;
            的替代代码:
       if(result == null)
             ;
       else
            do something useful;
          替代代码将有效的逻辑放在了和前置代码相邻的内存块中

         如果你不知道这些替代代码, 看完后你也许激动不以, 迅速将它们应用到实践, 但是请稍等, 考虑一个问题, 坐你身边同行们是否认同这些代码? 这些代码是否会降低你程序的可读性及可维护性? 
      
        我实现了一个简单的快速排序算法, 代码片段如下:

        /* x 中存放N个随机整数*/

        private void sort(int l,int r){
  
           if(l > r)
               return;
  
          int m = qsort(l,r);
          sort(l,m - 1);
          sort(m + 1,r);
       }
 
      /**
         * 以最左元素为比较元素,实现快速排序
      */
      private int qsort(int l,int r){
  
          int m = l;
  
          if(l >= r)
             return l;
  
          for(i = l + 1; i <=r; i++) {
            if(x[i] < x[l]){
               swap(++m, i);
            } 
          }
  
          swap(l, m);
  
          return m;
      }
 

      private void swap(int a, int b){

           x[a] ^= x[b];
           x[b] ^= x[a];
           x[a] ^= x[b];
       }

       对10个[0,100]的随机数进行排序, 打印结果如下:
       sourceData:
          44,97,55,86,94,13,34,89,12,29
      quickSort:
           0,12,29,34,44,0,0,0,0,97


          这些0是从哪里来的? 为什么会得出这种结果?

         仔细观察结果发现, 除了0之外, 其它的数都排列正确. 这使我并没有马上检查qsort方法, 而是把原来的swap方法改成了庶民的版本:


          int temp = x[a];
          x[a] = x[b];
          x[b] = temp;

         重新编译, 打印结果:
         sourceData:
             8,69,18,34,29,97,0,64,98,84
         quickSort:
             0,8,18,29,34,64,69,84,97,98

         重新检查swap方法, 发现当两个参数相等时, swap将x[a],x[b]全部置0, 没错, 此时x[a],x[b]本来就指向同一个位置, 在进行第一步x[a] ^= x[b]操作时, x[a]就变成了0, 此后的异或没有半点用处. 当然qsort方法的代码大概是快速排序中最简单的, 同时也是性能最差的, 在极端的情况下它会退化, 有N个改进版本, 让我们看一下第二个版本...哦, 好像偏题了.

        我的结论, 比起不起眼的性能提升, 提高程序的可读性和可维护性更加重要. 在web应用中, 速度的瓶颈主要是算法的设计, 数据库的优化, SQL语句的优化, 网络的速度, 机器的性能.


 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值