摘自传智播客
package test; public class Arithmetic4 { public static void main(String[] args) { //问题:计算求出1到10000的所有质数 //问题:计算求出1到100000000的所有质数 int num = 1000000; /* * 方案一 */ long start = System.currentTimeMillis(); for(int i=1;i<num;i++) { for(int j=2;j<i;j++) { if(i%j==0) break; if(j==i-1) System.out.println(i); } } System.out.println("-----------------------"); long end1 = System.currentTimeMillis(); /* * 方案二 */ System.out.println(3); for(int i=1;i<=num;i++) { for(int j=2;j<=Math.sqrt(i);j++) { if(i%j==0) break; if(j==(int)Math.sqrt(i)) System.out.println(i); } } System.out.println("-----------------------"); long end2 = System.currentTimeMillis(); /* * 方案三 */ System.out.println(3); for(int i=1;i<=num;i+=2) { for(int j=2;j<=Math.sqrt(i);j++) { if(i%j==0) break; if(j==(int)Math.sqrt(i)) System.out.println(i); } } System.out.println("----------------"); long end3 = System.currentTimeMillis(); /* * 方案四 */ int[] nums = new int[100]; nums[0] = 2; int temp = 1; for(int i=2;i<num;i++) { for(int j=0;j<temp;j++) { if(i%nums[j]==0) break; if((j+1)==temp) { if(temp == nums.length) { int[] tempNums = new int[nums.length*2]; for(int k=0;k<nums.length;k++) { tempNums[k] = nums[k]; } nums = tempNums; } nums[temp] = i; temp++; } } } for(int i=1;nums[i]!=0;i++) { System.out.println(nums[i]); } long end4 = System.currentTimeMillis(); /* * 时间对比 */ System.out.println("方案一:"+(end1-start)+"ms"); System.out.println("方案二:"+(end2-end1)+"ms"); System.out.println("方案三:"+(end3-end2)+"ms"); System.out.println("方案四:"+(end4-end3)+"ms"); } }
从方案一到方案四都是优化了计算次数,为什么方案四所用时间反而大于方案三和方案四呢?
原因在于程序运行时间并没有像我们预期的那样,我们忽略了一些小细节,就是不同的操作符所用时间是不同的,当循环数足够大时,它们的差值能盖过你所优化的时间。
小实验:
long start = System.currentTimeMillis(); int[] num = new int[10]; for(int i = 0;i<100000000;i++) { if(num[1]==1) ; } long end = System.currentTimeMillis(); System.out.println((end-start) + "ms");
long start = System.currentTimeMillis(); int j = 0; for(int i = 0;i<100000000;i++) { j++; } long end = System.currentTimeMillis(); System.out.println((end-start) + "ms");
像这样对运算符进行时间评估,可以发现从数组取值所花时间明显高于其他运算符。
所以:在算法设计时,不要忽略了一些简单的行为++ [] ==,这些操作需要开销时间的。