Java循环优化案例
提取循环不变量
优化前:

for (int i = 0; i < list.size(); i++) {
int value = list.get(i) * 100; // 每次循环都计算
// 处理value
}
优化后:
int size = list.size(); // 提取循环不变量
for (int i = 0; i < size; i++) {
int value = list.get(i) * 100;
// 处理value
}
减少方法调用
优化前:
for (int i = 0; i < 1000; i++) {
String str = Integer.toString(i);
System.out.println(str); // 每次循环调用System.out
}
优化后:
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
sb.append(i).append("\n");
}
System.out.println(sb.toString()); // 一次性输出
使用局部变量
优化前:
double sum = 0;
for (int i = 0; i < 1000000; i++) {
sum += Math.sqrt(i);
// 其他操作
}
优化后:
double sum = 0;
double sqrtCache;
for (int i = 0; i < 1000000; i++) {
sqrtCache = Math.sqrt(i); // 使用局部变量
sum += sqrtCache;
}
循环展开
优化前:
for (int i = 0; i < 1000; i++) {
a[i] = b[i] + c[i];
}
优化后:
for (int i = 0; i < 1000; i += 4) {
a[i] = b[i] + c[i];
a[i+1] = b[i+1] + c[i+1];
a[i+2] = b[i+2] + c[i+2];
a[i+3] = b[i+3] + c[i+3];
}
使用增强for循环
优化前:
List<String> list = new ArrayList<>();
for (int i = 0; i < list.size(); i++) {
String item = list.get(i);
// 处理item
}
优化后:
List<String> list = new ArrayList<>();
for (String item : list) { // 使用增强for循环
// 处理item
}
避免重复计算
优化前:
for (int i = 0; i < 100; i++) {
int result = calculate(i) * (array.length - 1);
// 使用result
}
优化后:
int len = array.length - 1;
for (int i = 0; i < 100; i++) {
int result = calculate(i) * len; // len在循环外计算
// 使用result
}
使用数组代替集合
优化前:
List<Integer> list = new ArrayList<>();
for (int i = 0; i < 1000000; i++) {
list.add(i);
}
优化后:
int[] array = new int[1000000];
for (int i = 0; i < 1000000; i++) {
array[i] = i; // 数组操作更快
}
提前退出循环
优化前:
boolean found = false;
for (int i = 0; i < 1000; i++) {
if (array[i] == target) {
found = true;
}
}
优化后:
boolean found = false;
for (int i = 0; i < 1000; i++) {
if (array[i] == target) {
found = true;
break; // 找到后立即退出
}
}
性能对比示例
// 测试代码
public class LoopOptimization {
public static void main(String[] args) {
// 测试数据
int[] data = new int[10000000];
for (int i = 0; i < data.length; i++) {
data[i] = i;
}
// 未优化版本
long start1 = System.currentTimeMillis();
int sum1 = 0;
for (int i = 0; i < data.length; i++) {
sum1 += data[i];
}
long end1 = System.currentTimeMillis();
System.out.println("未优化: " + (end1 - start1) + "ms");
// 优化版本(使用局部变量和循环展开)
long start2 = System.currentTimeMillis();
int sum2 = 0;
int len = data.length;
for (int i = 0; i < len; i += 4) {
sum2 += data[i];
if (i + 1 < len) sum2 += data[i + 1];
if (i + 2 < len) sum2 += data[i + 2];
if (i + 3 < len) sum2 += data[i + 3];
}
long end2 = System.currentTimeMillis();
System.out.println("优化后: " + (end2 - start2) + "ms");
}
}
- 提取不变量:将循环内不变的表达式移到循环外
- 减少方法调用:避免在循环中频繁调用高开销方法
- 使用局部变量:减少成员变量的访问开销
- 适当展开:减少循环控制开销
- 使用适当的数据结构:数组优于集合,ArrayList优于LinkedList
- 提前退出:使用break、continue减少不必要的迭代
- 避免装箱拆箱:使用基本类型而不是包装类
注意事项
- 优化前先进行性能分析,确定瓶颈
- 保持代码可读性,避免过度优化
- 不同JVM和硬件环境下的效果可能不同
- 优化时要考虑Java的即时编译(JIT)特性