Chinaunix首页 | 论坛 | 博客
  • 博客访问: 248735
  • 博文数量: 44
  • 博客积分: 1052
  • 博客等级: 少尉
  • 技术积分: 742
  • 用 户 组: 普通用户
  • 注册时间: 2010-12-17 16:51
文章分类

全部博文(44)

文章存档

2013年(7)

2012年(14)

2011年(23)

分类: C/C++

2011-11-01 21:32:55

看《programming pearls》里面有几段代码是关于加速查找算法,而且是顺序查找。感觉十分厉害,所以贴出来。

一般的顺序查找代码如下(算法1):
  1. #define MAXN 1000002
  2. int n;
  3. int x[MAXN];

  4. int seqsearch1(int t) /* 在数组x[0...n-1]中查找t */
  5. {
  6.     int i;
  7.     for(i = 0; i < n; i++)
  8.         if(x[i] == t)
  9.             return i;
  10.     return -1;
  11. }
我们要写顺序查找,应该也就这么写的。既然都是顺序查找了,还能怎样加速这个程序呢?

算法2:
  1. int seqsearch2(int t)
  2. {
  3.     int i;
  4.     int hold = x[n];

  5.     x[n] = t;                /* 将t放到x[0...n-1]之后,作为哨兵 */
  6.     for(i = 0; ; i++)        /* 这样做的目的是:for循环里就没有i
  7.         if(x[i] == t)
  8.             break;
  9.     x[n] = hold;
  10.     if(i == n)
  11.         return -1;
  12.     else
  13.         return i;
  14. }
算法3:
  1. int seqsearch3(int t)
  2. {
  3.     int i;
  4.     int hold = x[n];

  5.     x[n] = t;
  6.     for(i = 0; ; i+=8)    /* 对的,循环展开,展开8次 */
  7.     {
  8.         if(x[i] == t) { break; }
  9.         if(x[i+1] == t) { i += 1; break; }
  10.         if(x[i+2] == t) { i += 2; break; }
  11.         if(x[i+3] == t) { i += 3; break; }
  12.         if(x[i+4] == t) { i += 4; break; }
  13.         if(x[i+5] == t) { i += 5; break; }
  14.         if(x[i+6] == t) { i += 6; break; }
  15.         if(x[i+7] == t) { i += 7; break; }
  16.     }
  17.     x[n] = hold;
  18.     if(i == n)
  19.         return -1;
  20.     else
  21.         return i;
  22. }
对这几段代码的性能测试结果如下:
  1. [zxg@zxg-pc 5chp]$ ./a.out
  2. 100000 
  3. alg:1    n:100000    time:160.20ms              # 算法 seqsearch1
  4. alg:2    n:100000    time:131.20ms              # 算法 seqsearch2
  5. alg:3    n:100000    time:83.38ms               # 算法 seqsearch3
  6. alg:4    n:100000    time:81.95ms               # 算法 seqsearch4, 该算法是对循环作了16次展开
  7. 200000
  8. alg:1    n:100000    time:320.67ms              
  9. alg:2    n:100000    time:252.03ms           
  10. alg:3    n:100000    time:167.29ms          
  11. alg:4    n:100000    time:163.75ms             
从上面可以看出,算法2,要比算法1快了一点点, 但循环展开算法加速了接近一倍,这是很可观的加速。我还试了对循环展开16次, 但发现和展开8次的比较没什么变化,说明循环展开也不是越多就越厉害。

上面的程序编译时没有打开优化选项,下面是用gcc -O3来编译的。
明显还是编译器的优化更牛一些。
  1. [zxg@zxg-pc 5chp]$ ./opt-seq
  2. 100000
  3. alg:1 n:100000 time:49.26ms
  4. alg:2 n:100000 time:33.32ms
  5. alg:3 n:100000 time:30.55ms
  6. alg:4 n:100000 time:30.90ms
  7. 200000
  8. alg:1 n:200000 time:104.13ms
  9. alg:2 n:200000 time:81.35ms
  10. alg:3 n:200000 time:83.84ms
  11. alg:4 n:200000 time:75.47ms








阅读(1697) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~