1.多层嵌套循环
stratTime = System.nanoTime();
for (int i = 0; i <10000 ; i++) {
for (int j = 0; j < 100; j++) {
for (int k = 0; k < 10; k++) {
testFunction(i, j, k);
}
}
}
System.out.println("外大内小耗时:"+ (endTime - stratTime));
优化后:
stratTime = System.nanoTime();
for (int i = 0; i <10 ; i++) {
for (int j = 0; j < 100; j++) {
for (int k = 0; k < 10000; k++) {
testFunction(i, j, k);
}
}
}
endTime = System.nanoTime();
System.out.println("外小内大耗时:"+(endTime - stratTime));
两者耗时对比:
外大内小耗时:1582127649
外小内大耗时:761666633
优化原理
我们先分析原代码循环变量在实例化、初始化、比较、自增等方面的耗时情况:
优化前:
变量 | 实例化(次数) | 初始化(次数) | 比较(次数) | 自增(次数) |
---|---|---|---|---|
i | 1 | 1 | 10000 | 10000 |
j | 10000 | 10000 | 10000*100 | 10000*100 |
k | 10000*100 | 10000*100 | 1000010010 | 1000010010 |
优化后:
变量 | 实例化(次数) | 初始化(次数) | 比较(次数) | 自增(次数) |
---|---|---|---|---|
i | 1 | 1 | 10 | 10 |
j | 10 | 10 | 10*100 | 10*100 |
k | 10*100 | 10*100 | 1010010000 | 1010010000 |
结论
嵌套循环应该遵循“外小内大
”的原则
2.循环变量的实例化应放在循环外
在1.中优化后的代码基础上,进行二次优化:
stratTime = System.nanoTime();
int i, j, k;
for (i = 0; i <10 ; i++) {
for (j = 0; j < 100; j++) {
for (k = 0; k < 10000; k++) {
testFunction(i, j, k);
}
}
}
endTime = System.nanoTime();
System.out.println("提取出循环内变量后耗时:"+(endTime - stratTime));
结果如下:
外小内大耗时:761666633
提取出循环内变量后耗时:748479323
优化并不明显,但是当循环越大时,耗时会差距更大
## 优化原理
优化后:
变量 | 实例化(次数) | 初始化(次数) | 比较(次数) | 自增(次数) |
---|---|---|---|---|
i | 1 | 1 | 10 | 10 |
j | 1 | 10 | 10*100 | 10*100 |
k | 1 | 10*100 | 1010010000 | 1010010000 |
结论
循环变量的实例化应该尽量放在循环外进行
3.提取与循环无关的表达式
stratTime = System.nanoTime();
for (int i = 0; i < 10000000; i++) {
i=i*a*b;
}
endTime = System.nanoTime();
System.out.println("未提取耗时:"+(endTime - stratTime));
优化后:
stratTime = System.nanoTime();
c = a*b;
for (int i = 0; i < 10000000; i++) {
i=i*c;
}
endTime = System.nanoTime();
System.out.println("已提取耗时:"+(endTime - stratTime));
结论:
代码中a+b与我们的循环无关,所以应该把它放到外面,避免重复计算。
4.消除循环终止判断时的方法调用
stratTime = System.nanoTime();
for (int i = 0; i < list.size(); i++) {
}
endTime = System.nanoTime();
System.out.println("未优化list耗时:"+(endTime - stratTime));
优化后:
stratTime = System.nanoTime();
int size = list.size();
for (int i = 0; i < size; i++) {
}
endTime = System.nanoTime();
System.out.println("优化list耗时:"+(endTime - stratTime));
结论
list.size()每次循环都会被执行一次,这无疑会影响程序的性能,所以应该将其放到循环外面,用一个变量来代替。
5.异常捕获
stratTime = System.nanoTime();
for (int i = 0; i < 10000000; i++) {
try {
} catch (Exception e) {
}
}
endTime = System.nanoTime();
System.out.println("在内部捕获异常耗时:"+(endTime - stratTime));
优化后:
stratTime = System.nanoTime();
try {
for (int i = 0; i < 10000000; i++) {
}
} catch (Exception e) {
}
endTime = System.nanoTime();
System.out.println("在外部捕获异常耗时:"+(endTime - stratTime));
结论
捕获异常是很耗资源的,所以不要讲try catch放到循环内部。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。