for(int i=1;i<=100;i++)
作为程序猿,我们很喜欢使用这种for循环。
可是,当中隐含着一个重要的问题。
过多的编程经历可能使我们的思维产生了一些误解,在上面的for循环中,因为我们在以往过多的编程经历中更加关注for循环体中的内容,导致我们差点儿忽略了那个小i的存在,它扮演着作为计数器的一个“小角色”,我们忽略了它,殊不知它的“饭量”也是不小的哦~
#include<stdio.h> #include<time.h> int main() { int temp; /********************************/ temp=clock(); for(int i=1;i<=100;i++); printf("%d ",clock()-temp); /********************************/ temp=clock(); for(int i=1;i<=1000000000;i++); printf("%d ",clock()-temp); /********************************/ return 0; }
程序执行结果是:
0
3000
这样看来,那个小i所耗掉的执行时间也是很可观的。一些编程新手觉得程序的执行时间是由循环次数决定的,这样说对于上面的那个程序貌似是对的,可是没有说到本质。略微懂编程的人都能知道,程序的执行时间是由程序的运算次数决定的,明显加减法要比乘除法快。
对于觉得执行时间由循环次数决定的想法是错误的,能够看以下的程序:
#include<stdio.h> #include<time.h> int main() { int n,temp; /********************************/ temp=clock(); n=1; for(int i=1;i<=100000000;i++) { n++,n--; n++,n--; n++,n--; n++,n--; n++,n--; n++,n--; n++,n--; n++,n--; n++,n--; n++,n--; } printf("%d ",clock()-temp); /********************************/ temp=clock(); n=1; for(int i=1;i<=150000000;i++)n++,n--; printf("%d ",clock()-temp); /********************************/ return 0; }
程序执行结果:
6291
901
前者的循环次数有一亿次,而后者的循环次数有一亿五千万次,可是后者更快,是由于前者的运算次数多。深入分析,前者的加减法运算次数大约是100000000+100000000*20=2100000000即21亿,比較次数(i<=100000000)是一亿次;而后者加减法运算次数是150000000+150000000*2=450000000即4亿5千万次,比較次数(i<=150000000)是一亿五千万次。前者比后者多了16亿5千万次的加减法,后者比前者多了5千万次的比較,依据数据大小的不同可能会有所差异。
不管怎样,我们一方面要认识到决定执行时间的因素究竟有哪些,还有一方面,我们更不能忽视掉for循环中小i的作用和消耗,尤其在小i嵌入一个二层循环中。
我之前做过一道算法题,我的程序要跑4s,而我同学给我优化的程序仅仅要跑不到1s,可是我始终找不到原因,由于推导的公式中累加的次数是一样的,仅仅只是我的循环是n*sqrt(n),而他的是n*lg(n)。我当时仅仅注重了公式中数据的累加,即我仅仅注重了循环体中的内容,忽视掉了小i也有做加法,尤其是套在一个数据量高达五十万的二层循环中,这时候,小i的影响就凸显出来了,由于在这个问题上,我和我的同学相差的地方仅仅有那个循环次数不一样了(公式中的累加肯定是一样的,不然得出的结果是不一样且不对的)。所以看来,有些时候须要特别的控制一下程序的循环次数,在算法一样的情况下,尤其对于多层循环的程序,降低循环次数可以出现意想不到的收益。