对于提升代码的运行效率 优化一两处代码对于整体的运行效率意义不大,如果能够把写优质代码的习惯保持在一个项目中这样就非常有用。
小编建议在项目编写代码的过程中,多注意代码编写细节,选择最优最简洁的编写方案,会减少很多生产上位置的错误,也会减少很多排查问题的工作量。
代码优化的最终目标:
减少代码的体积
提升代码的运行效率
减少生产Bug
减少变量的重复计算
对于方法的调用,即使方法中只有一句语句,也是有消耗的,包括创建栈帧、调用方法时保护现场、调用方法完毕时恢复现场等。
for(int i= 0 ; i < list.size(); i++){
........
}
上面这个for循环处理逻辑我想大家在开发过程中经常使用,如果实际业务中循环次数比较少 对于整体性能影响不大,但是在高并发、并且循环次数多的情况下就会影响性能,可以改为:
for(int i= 0,length = list.size ; i < length; i++){
........
}
如上代码块,当list.size()很大的时候,就会减少非常多的性能消耗。
使用懒加载,需要的使用才去创建
请看如下代码:
String val = "123"; if(i == 1){ list.add(val);
}
可以修改为:
if(i == 1){
String val = "123"; list.add(val);
}
try...catch...不在循环中使用,可以放到最外层进行捕捉
指定类、方法的final修饰符
大家都知道带有final修饰符的类是不可派生的,例如java.lang.String 整个类都是final的,如果为类制定final修饰符可以让类不被继承,为方法指定final修饰符可以让方法不可以被重写。
如果指定了一个类为final,该类所有的方法都是final。Java编译器会寻找机会内联所有的final方法,内联对于提升Java运行效率作用重大,具体参见Java运行期优化。此举能够使性能平均提高50%。
尽量重用对象
比如String对象的使用,如果出现多个字符串连接时应该使用StringBuilder/StringBuffer代替。Java的虚拟机需要花费时间生成对象,还要花费时间把对象进行垃圾回收和处理,所以生成过多的对象会对程序的性能带来很大的影响。
使用局部变量
在调用方法的时候传递参数和在调用中创建的临时变量都可以保存在栈中,这样速度较快,而其他的变量(如静态变量、实例变量等),都在堆中创建,速度比较慢。
另外,栈中创建的变量,随着方法的执行结束,这些数据就没了,不需要再额外的垃圾回收。
流要使用完成后要及时关闭
在实际开发过程中数据库连接、I/O流等使用时,使用完毕后要进行关闭释放资源,不然会降低系统性能,增加内存开销,甚至严重生产Bug。
使用System.arraycopy()复制大量数据
复制大量数据的时候可以使用java.lang.System.arraycopy() 方法复制指定的源数组的数组,在指定的位置开始,到目标数组的指定位置。
使用移位运算符
java中有三种移位运算符:
<< : 左移运算符,num << 1,相当于num乘以2>> : 右移运算符,num >> 1,相当于num除以2>>> : 无符号右移,忽略符号位,空位都以0补齐
用移位操作可以极大地提高性能,因为在计算机底层,对位的操作是最方便、最快的。
循环内不要创建对象引用
例如:
for(int i = 0; i < 100; i++){ Object obj = new Object();
........
}
上述代码会在内存中有100个Object对象,如果循环的次数更多就会消耗更多的内存,可以修改为:
Object obj = null; for (int i = 0; i < 100; i++)
{
obj = new Object();
.......
}
上述代码处理,在内存中只有一份Object 对象,每次new 的时候指向不同的Object,大大的减少内存的消耗。
静态变量合理使用
如果对某个对象定义为static 静态变量,那么系统将不会回收这个对象所占的内存,例如:
public class Test{
private static A = new A();
}
清除不需要的会话
应用服务器设置的默认会话超时的时间一般为30分钟,如果应用服务器需要保存更多的会话时,如果内存不足那么操作系统会把部分数据转移到磁盘,应用服务器也可能根据MRU(最近最频繁使用)算法把部分不活跃的会话转储到磁盘,甚至可能抛出内存不足的异常。
如果会话要被转储到磁盘,那么必须要先被序列化,在大规模集群中,对对象进行序列化的代价是很昂贵的。
可以及时调用HttpSession的invalidate()方法清除不再需要的会话。
声明大写命名的static final常量
在系统编译期间就把内容放入常量池中,避免运行期间计算生成常量的值。并且将常量的名字以大写命名可以方便区分出常量与变量 。
不要创建一些不使用的对象,不要导入一些不使用的类
这毫无用处,如果代码中出现”The value of the local variable i is not used”、”The import java.util is never used”,那么就删除这些无用的内容 。
程序运行过程中尽量不使用反射
反射是Java提供给用户一个很强大的功能,功能强大往往意味着效率不高。
字符串变量和字符串常量equals的时候将字符串常量写在前面
例如:
String val = “123”; if (val.equals(“123”)){
.....…
}
可以修改为:
String val = “123”; if (“ 123”.equals(val)){
.....…
}
可以有效避免空指针异常。
字符串基本类型转换
基本数据类型.toString()是最快的方式、String.valueOf(数据)次之、数据+””最慢
long或者Long初始赋值时,使用大写的L而不是小写的l,因为字母l极易与数字1混淆。
好了,小萌暂时就整理这么多。每一点小小的优化就能规避掉很多未知的代码,也能让自己的代码更整洁、执行效率更高效。
更多精彩内容欢迎关注“IT实战联盟”公众号哦~~~
注意:本文归作者所有,未经作者允许,不得转载