You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何提升Java循环中代码执行性能?两类计算代码优化问询

循环内数值计算的性能优化咨询

单次执行时Code 1比Code 2快,但在5000万次循环中Code 1性能最差。现寻求以下方案:

  • 是否可优化Code 1使其循环性能提升?
  • 有没有更高效的方式完成循环内的这类计算?

补充:经@Sweeper确认,两类代码中Code 1实际执行速度均更慢,重点聚焦循环内计算的性能优化。


原始测试代码

int [] arr1 = new int[50000000];
for (int i = 0; i < 50000000; i++) {
    arr1[i] = i + 1000;
}

//code 1:
long startTime1 = System.nanoTime();
int som1 = 426;
double a1 = (double) ((((double) Math.round((double) Math.pow((double) arr1[arr1.length - 1] / (double) som1, 2)) - 1) / 50 % 1) * 50) + 1;
int a2 = (int) Math.round(a1);
long estimatedTime1 = System.nanoTime() - startTime1;
System.out.println("Code 1: " + estimatedTime1);

//code 2:
long startTime2 = System.nanoTime();
int som2 = 426;
double a3 = (double) arr1[arr1.length - 1] / (double) som2;
double a4 = (double) (Math.round(a3 * a3) - 1);
double a5 = (double) a4 / 50;
double a6 = (double) Math.floor(a5);
double a7 = (double) ((a5 - a6) * 50) + 1;
int a8 = (int) Math.round(a7);
long estimatedTime2 = System.nanoTime() - startTime2;
System.out.println("Code 2: " + estimatedTime2);

//code 1 inside for loop:
long startTime3 = System.nanoTime();
int som3 = 426;
for (int j1 = 0; j1 < arr1.length; j1++) {
    double a9 = (double) ((((double) Math.round((double) Math.pow((double) arr1[j1] / (double) som1, 2)) - 1) / 50 % 1) * 50) + 1;
    int a10 = (int) Math.round(a9);
}
long estimatedTime3 = System.nanoTime() - startTime3;
System.out.println("Code 1 inside for loop: " + estimatedTime3);

//code 2 inside for loop:
long startTime4 = System.nanoTime();
int som4 = 426;
for (int j2 = 0; j2 < arr1.length; j2++) {
    double a11 = (double) arr1[j2] / (double) som4;
    double a12 = (double) (Math.round(a11 * a11) - 1);
    double a13 = (double) a12 / 50;
    double a14 = (double) Math.floor(a13);
    double a15 = (double) ((a13 - a14) * 50) + 1;
    int a16 = (int) Math.round(a15);
}
long estimatedTime4 = System.nanoTime() - startTime4;
System.out.println("Code 2 inside for loop: " + estimatedTime4);

优化方案

1. Code 1针对性优化:替换Math.pow核心瓶颈

Code 1的最大性能问题是Math.pow(x,2),这个通用幂运算函数内部逻辑复杂,远不如直接用x*x高效。循环5000万次时,这个开销会被无限放大。同时提前将常量som转为double,避免循环内重复类型转换。

修改后的Code 1循环版本:

long startTime3 = System.nanoTime();
int som3 = 426;
double somDouble = 426.0; // 提前转double,减少循环内转换开销
for (int j1 = 0; j1 < arr1.length; j1++) {
    double x = arr1[j1] / somDouble;
    double squared = x * x; // 替换Math.pow(x,2)
    double a9 = ((Math.round(squared) - 1) / 50 % 1) * 50 + 1;
    int a10 = (int) Math.round(a9);
}
long estimatedTime3 = System.nanoTime() - startTime3;
System.out.println("Optimized Code 1 inside for loop: " + estimatedTime3);

2. 通用循环计算优化技巧

  • 简化数学运算逻辑:分析计算式的等价形式,减少冗余运算。比如(a /50 %1)*50等价于a %50(正数场景下),可直接替换,省去两次浮点运算:
    原计算((Math.round(squared)-1)/50 %1)*50 +1可简化为((Math.round(squared)-1) %50) +1
  • 优先用整数运算替代浮点:如果业务允许,将计算逻辑转移到整数域。比如先计算arr1[j1] * arr1[j1](用long避免溢出),再除以som*som后取整,减少浮点转换和运算开销:
    long somLong = 426L;
    long somSquared = somLong * somLong;
    for (int j1 = 0; j1 < arr1.length; j1++) {
        long numSquared = (long)arr1[j1] * arr1[j1];
        long rounded = Math.round((double)numSquared / somSquared);
        int result = (int)((rounded -1) %50) +1;
    }
    
  • 并行化处理大循环:利用Java并行流或手动多线程,把5000万次循环拆分到多个CPU核心执行:
    long startTimeParallel = System.nanoTime();
    int som = 426;
    double somDouble = 426.0;
    Arrays.stream(arr1).parallel().forEach(num -> {
        double x = num / somDouble;
        double squared = x * x;
        int result = (int) Math.round(((Math.round(squared)-1) %50) +1);
    });
    long estimatedTimeParallel = System.nanoTime() - startTimeParallel;
    System.out.println("Parallel optimized version: " + estimatedTimeParallel);
    

3. 优化验证注意事项

JVM的即时编译(JIT)会对循环做自动优化,不同JDK版本、硬件环境的测试结果可能有差异。建议多次运行取平均结果,或关闭JIT的部分优化选项,确保测试数据准确。


内容的提问来源于stack exchange,提问作者JOAO12

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 03:27:39