浅浅谈效率的持续改进

效率,一直是多有程序员追逐的目标,每个人在实践的过程中都发现了很多提高效率的办法,从程序结构的改进到对CPU指令集的研究。各种奇技淫巧都不惜一用。

但通常的情况下,效率是在不牺牲代码可读性和稳定性的基础上提高的,除非有很变态的要求。

我个人在实践中也经常尝试提高程序效率,下面只说说自己的一点拙见

举个例子,求前5000个素数

素数,就是只能被1和它自身整除的数。通过这个定义,很容易写出一个直观的算法

 

 1 #include <math.h>
 2 void gcd(int num)
 3 {
 4     int j;
 5     bool prime = true;
 6     for(int i = 0, k = 2; i < num; k ++)
 7     {
 8         for(j = 2; j <= k; j ++)
 9         {
10             if(k%j==0)
11             {
12                 prime  = false;
13                 break;
14 
15             }
16         }
17         if(prime)
18         {
19         //    cout << i << ":" << k << endl;
20             i ++;
21         }
22         else
23         {
24             prime  = true;
25         }
26     }
27 }

 

但是,当一个数是素数时,它必须尝试这整除2~N所有的整数,但实际上,只需要整除到它的平方根就可以确定其是否是素数了。

 

 1 #include <math.h>
 2 void gcd(int num)
 3 {
 4     int j;
 5     bool b = true;
 6     for(int i = 0, k = 2; i < num; k ++)
 7     {
 8         for(j = 2; j <= int(sqrt(double(k))); j ++)
 9         {
10             if(k%j==0)
11             {
12                 b = false;
13                 break;
14 
15             }
16         }
17         if(b)
18         {
19         //    cout << i << ":" << k << endl;
20             i ++;
21         }
22         else
23         {
24             b = true;
25         }
26     }
27 }

现在,效率有了显著提高。

但还有一点小小的问题,

for(j = 2; j <= int(sqrt(doutle(k))); j ++)

这里,每次循环都要重新计算k的平方根。当日,编译器也许会帮你优化掉这个地方,用一个临时变量代替sqrt(k),但有一条原则是永远不要指望编译器帮你优化,毕竟不是每个编译器都会做这样的工作的。所以,我们应该自己做,至少这里很明显的,我们可以自己优化

int m = sqrt(double(k));
for(j = 2; j <= m; j ++)

经过三次改进之后,程序的效率有了明显提高。

这里只是举了个例子,并不想深入研究素数算法。也就是说,现有的逻辑和算法通常是存在这改进空间的。

再举个例子,三维数组

我们知道std::vector是允许拷贝的,也就是说vector<vector<vector<T> > >这个定义是合法的,虽然显得有点难看。

但是,你知道它潜在的效率隐患吗?

如果数组的大小是固定的,在整个运行过程中不会被改变,那么我们初始化一次也就行了。并没什么大的影响

但当最外层的vector需要增长的时候,问题就大了。想想,第二层的vector需要复制到新的存储区,而第二层中每个vector本身有是个vector的集合,也就是当最外层增长时,需要做M*N*P次拷贝。

解决方法就是一定不要用这种嵌套的vector。可以模拟三维数组,比如散列表,用struct{x,y,z}做键。

以上这些,都是不需要什么数学知识就可以做到的。关键在于认真分析和发现。

就说这么多吧,希望多交流

posted @ 2008-10-14 16:48  刺儿头  阅读(229)  评论(0编辑  收藏  举报