————————————————————————————————————————
"Premature optimization is the root of all evil."
”过早的优化是一切问题的根源“
————————————————————————————————————————
上面这句话出自《计算机编程艺术卷》的作者高纳德教授,在计算机界大名鼎鼎。。这句话很好理解,在你编程的时候尽量不要在一开始就为了优化它而用尽奇技淫巧。这样往往得不偿失。通常只有当我的程序在成功运行后,然后对效率有很高的要求,但明显自己的程序未达要求的时候,才去进行优化。过早的优化有时会让人十分头疼的。这篇文章讨论的是Java语言本身提高性能的一些小技巧,并不会涉及native代码,或者算法上的优化内容。当然也许你感觉所提升的性能不过是在ms级别的,从而认为它微不足道,然后在如今这个大数据时代,一点点的优化乘以海量的数据,就会有很显著的效果。
下面进入正题,曾经给我印象很深的一种优化技巧是在《Java性能优化》见到的一个方法:展开循环。然而它真的可行吗?
for(int i=0;i<9999999;i++) array[i]=i; //展开for循环 for(int i=0;i<9999999;i+=3){ array[i]=i; array[i+1]=i+1; array[i+2]=i+2; }效率究竟怎么样呢?我们可以写一段简单的代码来测试:
int size = 9999999;//7个9 int [] array = new int[size]; long time = System.currentTimeMillis(); for(int i=0;i<size;i++) array[i]=i; time = System.currentTimeMillis()-time; System.out.println(time); time = System.currentTimeMillis(); for(int i=0;i<size;i+=3){ array[i]=i; array[i+1]=i+1; array[i+2]=i+2; } time = System.currentTimeMillis()-time; System.out.println(time);
int size = 9999999; Integer [] array = new Integer [size]; long time = System.currentTimeMillis(); for(int i=0;i<size;i++) array[i]=new Integer(i); time = System.currentTimeMillis()-time; System.out.println(time); time = System.currentTimeMillis(); for(int i=0;i<size;i+=3){ array[i]=new Integer(i); array[i+1]=new Integer(i+1); array[i+2]=new Integer(i+1); } time = System.currentTimeMillis()-time; System.out.println(time);结果是:第一个5483,第二个6423。是啊对象的话,确实比基本数据类型有较大差别,不过呢,展开之后却比不展开的慢了好多,而不是快了好多。。这当然不是偶然结果。多运行几次结果都是下面的要慢上好多。
double x = d * (lim / max) * sx;
double y = d * (lim / max) * sy;
可以写成
double depth = d * (lim / max);
double x = depth * sx;
double y = depth * sy;
很好理解吧。如果程序中有大量的重复运算便可以提取出来只运算一次就可以了。
for(int i=0;i<array.length;i++){ array[i]=i; } int size = array.length;//保存结果 for(int i=0;i<size;i++){ array[i]=i; }关于for循环(表达式1;表达式2;表达式3){ 循环体 }我们都知道循环的执行顺序,再每一次循环体执行结束后,都会去执行一次表达式2,来验证是否满足条件,所以如果一个数组的话,那么每一次都会调用一次求长度的操作,无形之中增加了开销。
int size = 100000000; int [] array = new int[size]; int [] array1 = new int[size]; for(int i=0;i<size;i++){ array[i]=i; array1[i]=i; } long time = System.currentTimeMillis(); for(int i=0;i<size;i++){ array[i]>>=8; } time = System.currentTimeMillis()-time; System.out.println(time); time = System.currentTimeMillis(); for(int i=0;i<size;i++){ array1[i]/=256; } time = System.currentTimeMillis()-time; System.out.println(time);其10次运行的结果:
boolean a = true; boolean b = false; int size = 1000000000; long time = System.currentTimeMillis(); for (int i = 0; i < size; i++) if(a&b){}; time = System.currentTimeMillis() - time; System.out.println(time); time = System.currentTimeMillis(); for (int i = 0; i < size; i++) if(a&&b){}; time = System.currentTimeMillis() - time; System.out.println(time);其10次输出结果: