记录项目开发过程中对于性能优化的事项。
性能优化的最终目的也就是为了减少代码运行时间和占用的内存。
进行性能调优的方法
使用System.currentTimeMillis来计算出代码运行的时间
long startTime = System.currentTimeMillis();
--代码内容--
long endTime = System.currentTimeMillis();
log.info("代码运算时间为:" + (endTime - startTime));
如果此块代码耗时过大,那就对代码进行细分,并且计算代码运行时间,查找可以优化的地方。
如:可分为
对数据库进行操作的代码。
对数据进行计算的代码。
记录事项
1、尽量少的对数据进行转型,以尽量少的操作获得自己想要的数据。
例如:在项目中需要获取redis中的数据,格式为JSONArray,一开始是这样获取的,一共转型了两次。
JSONArray baseInfoGeoJsonArr = JSON.parseArray(redisUtil.get(key).toString());
在数据量比较大的时候这种操作对于运行速度和内存的影响就凸显出来,于是减少转型次数,直接强转。
JSONArray baseInfoGeoJsonArr = (JSONArray) redisUtil.get(key);
优化后代码的运行时间比原来减少了三分之一
取出数据后要获取其中的数据
//原先代码
baseInfoJsonStr = dataJsonArr.getString(j);
baseInfoJsonArr = JSONObject.parseArray(baseInfoJsonStr);
//优化代码
baseInfoJsonArr = baseInfoGeoJsonArr.getJSONArray(j);
2、尽量少的创建对象,多重用对象
新建对象需要耗费时间,并且需要进行回收与处理,不仅影响代码速度并且耗费内存,所以要尽量少创建新的对象。比如不要在循环中重复new对象,可以在循环外创建对象,在循环中重用。
例:
for(int i = 0 ; i < dataList.size() ; i++) {
String s = dataList.get(i)
}
//优化后
String s;
for(int i = 0 ; i < dataList.size() ; i++) {
s = dataList.get(i)
}
如果该对象只在if中使用且不在循环中,则可以在if中创建,这样如果if判断没有通过则不用创建,节省资源。
if(x == 1) {
int a = 0;
......
}
3、尽量确定可扩展数据类型的容量
如:StringBuffer、HashMap
虽然StringBuffer的容量是动态的,但是如果超出当前容量需要扩容的话,也会消耗运行资源,所以要尽量确定StringBuffer的长度。
HashMap可以使用构造函数设置容量
public HashMap(int initialCapacity, float loadFactor);
4、可以不使用静态变量就不使用
因为静态变量不会被回收,会一直占用内存直到程序结束运行,所以尽量少使用静态变量以节省资源
5、在不考虑线程安全的情况下尽量不使用有线程安全机制的数据类型
线程安全牺牲了部分性能,因此在不考虑线程安全的情况下,使用没有线程安全机制的数据类型可以提升代码效率,如HashMap、ArrayList
6、尽量在finally块中释放资源
因为finally块中的代码是一定会执行的,所以应该尽量把关闭资源的代码写在这里,防止因为前面代码运行错误导致掉过后面代码,导致资源未能正确关闭而造成资源泄露的情况
7、无用的变量尽早释放
在方法中创建并使用的对象会随着方法的结束而释放,所以如果在对象使用结束后已经没有代码要执行了,那么可以等着方法结束对象自动释放,但是如果还有相当的代码要执行,那么此时手动释放对象是有利于节省资源的。
method () {
int a = 0;
.....
a = a +1;//对对象进行调用,不必进行释放
}
//进行释放
method () {
int a = 0;
.....
a = a +1;//对对象进行调用
.....
a = null;//释放对象
.....
}
8、尽量避免使用二维数组
二维数据占用的内存空间比一维数组多得多,大概10倍以上。
9、正确地使用ArrayList 和 LinkedList
ArrayList 底层是以数组形式实现的,LinkedList 底层是以链表形式实现的。
ArrayList 遍历效率高,而如果要对数据进行增删改则效率低
LinkedList 操作效率高,但是遍历效率低
所以要根据情况来选择使用哪一个,如果对数据变动不大,而且需要经常遍历,则选择ArrayList 反之则选择 LinkedList
10、 尽量使用System.arraycopy ()代替通过来循环复制数组
使用System.arraycopy() 来复制数组要比通过循环来复制数组节省更多的资源