前言:
优化代码,一个很重要的课题。可能有些人觉得没用,一些细小的地方有什么好修改的,改与不改对代码的运行效率有什么影响呢?这个问题我是真么考虑的,好比人吃饭,吃一粒米,没用,但是一万,十万呢,这样的效率就很可观了。
代码优化的目标是:
1.减小代码体积;
2.提高代码运行效率。
具体方法:
1.尽量指定类,方法的final修饰符
带有final的修饰符的类是不可派生的。在java核心API中,有许多应用final的例子,例如:java.long. String,整个类都是final的。为类指定final修饰符可以让类不可被继承,为方法指定final修饰符可以让方法不被重写。如果指定了一个类为final,则该类所有的方法都是final的。
java编译器会寻找机会内联所有的final方法,内联对于提升java运行效率作用重大,大概能使性能提升50%。
内联:通常是用来消除调用函数时所需要的时间。
2.尽量复用对象
特别是String对象,出现字符串连接时应该使用StringBuffer /StringBuilder代替。由于java虚拟机不仅要花时间生成对象,以后可能还需要对这些对象进行垃圾回收和处理,因此,生成过多对象会给程序的性能带来很大影响。
3.尽可能使用局部变量
调用方法是传递的参数以及在调用中创建的临时变量都保存在栈中,相对速度比较快。其他变量如,静态变量,实例变量等,都在堆中创建,速度较慢。另外,栈中创建的变量,随着方法的运行结束,这些内容就消失了,不需要额外的垃圾回收。
4.及时关闭流
java编程过程中,进行的数据库连接,I/O流等操作时务必当心,在使用完毕后,应及时关闭流以释放资源。因为这些大对象的操作会造成系统大的开销,会大大影响程序运行效率。
5.尽量减少对变量的重复计算
明确概念,对方法的调用,即使方法中只有一条语句,也是要加载的。包括创建堆栈。
调用方法时保护现场,方法结束时恢复现场等。如:
for(int i=0;i<list.size();i++){
}
可以替换为:
for(int i=0,length=list.size(); i<length;i++){
}
这样,如果list.size()里的数据有很多时(如2000000左右),会减少很多性能消耗。
6.尽量使用懒加载策略,即在需要时才创建
如:
String str = "aaa";
if(i == 1) {
list.add(str);
}
可以替换为:
if(i == 1) {
String str = "aaa";
list.add(str);
}
7.慎用异常
异常对性能不利。抛出异常首先要创建一个新的对象,Throwable接口的构造函数调用名为filllnStackTrace()的本地同步方法,filllnStackTrace()方法检查堆栈,收集调用跟踪信息。
只要有异常被抛出,java虚拟机就必须调整调用堆栈,因为在处理过程中创建了一个新的对象。异常只能用于错误处理,不应该用来控制流程程序。
8.不要在循环中使用try···catch···,应该把它放到最外层。
9.如果能估计到待添加的内容长度,为底层以数组方式实现的集合,工具类指定初始长度。
比如ArrayList、LinkedList、StringBuilder、StringBuffer、HashMap、HashSet等等,
以StringBuilder为例:
(1) StringBuilder() //默认分配16个字符空间
(2) StringBuilder(int size) //默认分配size个字符空间
(3) StringBuilder(String str) //默认分配16个字符+str.length()个空间
可以通过类(不仅仅是StringBuilder)来设定它的初始化容量,这样可以明显提升性能。
比如StringBuilder吧,length表示当前的StringBuilder能保持的字符数量。因为当StringBuilder达到最大容量的时候,它会将自身容量加到当前的2倍在加2,无论何时,只要StringBuilder达到它的最大容量值,它就会创建一个新的字符数组然后将旧的字符数组里面的内容拷贝到新数组里是一个十分耗时的工作。
比如,一个字符数组大概要放5000个字符而不指定长度,最接近5000的2次幂是4096,那么:
(1) 在4096的基础上,在申请8194+2个大小的新数组,加起来相当于共申请了12292的内存空间,如果一开始就指定长度5000或5500的话,就能节省一倍的空间。
(2) 把原来的4096个字符拷贝到新的字符数组中,这样不仅浪费内存又降低代码运行效率。 所以,给底层以数组实现的集合、工具类设置一个合理的初始值是不会有错的。但是,注意,向HashMap这种以数组+链表实现的集合,别把初始值大小和你预估的大小设置的一样,因为一个table上连接一个对象的概率几乎为0。建议初始大小值设为2的N此幂,如果预估是2000个元素,设置成 new HashMap(128)、new HashMap(256)都可以。
10.当复制大量数据时,使用System.arraycopy()命令。
喜欢的小伙伴们可以搜索我们个人的微信公众号“程序员的成长之路”点击关注或扫描下方二维码