一个循环中的两个操作与两个循环在每个循环中执行相同的操作

Bal*_*ala 10 java performance loops

这个问题与这 两个循环体或一个(结果相同)相同, 但在我的情况下,我使用Java.

我有两个循环,运行十亿次.

int a = 188, b = 144, aMax = 0, bMax = 0;

for (int i = 0; i < 1000000000; i++) {
  int t = a ^ i;
  if (t > aMax) 
    aMax = t;     
}  

for (int i = 0; i < 1000000000; i++) {
  int t = b ^ i;
  if (t > bMax) 
    bMax = t;     
}  
Run Code Online (Sandbox Code Playgroud)

在我的机器中运行这两个循环所需的时间是4秒.当我将这两个循环融合到一个循环中并在该单循环中执行所有操作时,它将在2秒内运行.正如您所看到的那样,琐碎的操作构成了循环内容,因此需要恒定的时间.

我的问题是我在哪里获得这种性能提升?

我猜测性能在两个独立的循环中受影响的唯一可能的地方是它增加i并检查我是否<1000000000 20亿次而不是10亿次如果我将循环融合在一起.还有其他事吗?

谢谢!

ass*_*ias 5

如果你没有运行预热阶段,第一个循环可能会被优化和编译而不是第二个循环,而当你合并它们时,整个合并循环就会被编译.此外,使用该server选项和您的代码,大多数都会被优化掉,因为您不使用结果.

我已经运行了下面的测试,将每个循环以及合并循环放在他们自己的方法中,并热化JVM以确保所有内容都被编译.

结果(JVM选项:) -server -XX:+PrintCompilation:

  • 循环1 = 500ms
  • 循环2 = 900毫秒
  • 合并循环= 1,300毫秒

因此合并的循环稍微快一点,但不是那么多.

public static void main(String[] args) throws InterruptedException {

    for (int i = 0; i < 3; i++) {
        loop1();
        loop2();
        loopBoth();
    }

    long start = System.nanoTime();

    loop1();

    long end = System.nanoTime();
    System.out.println((end - start) / 1000000);

    start = System.nanoTime();
    loop2();
    end = System.nanoTime();
    System.out.println((end - start) / 1000000);

    start = System.nanoTime();
    loopBoth();
    end = System.nanoTime();
    System.out.println((end - start) / 1000000);
}

public static void loop1() {
    int a = 188, aMax = 0;
    for (int i = 0; i < 1000000000; i++) {
        int t = a ^ i;
        if (t > aMax) {
            aMax = t;
        }
    }
    System.out.println(aMax);
}

public static void loop2() {
    int b = 144, bMax = 0;
    for (int i = 0; i < 1000000000; i++) {
        int t = b ^ i;
        if (t > bMax) {
            bMax = t;
        }
    }
    System.out.println(bMax);
}

public static void loopBoth() {
    int a = 188, b = 144, aMax = 0, bMax = 0;

    for (int i = 0; i < 1000000000; i++) {
        int t = a ^ i;
        if (t > aMax) {
            aMax = t;
        }
        int u = b ^ i;
        if (u > bMax) {
            bMax = u;
        }
    }
    System.out.println(aMax);
    System.out.println(bMax);
}
Run Code Online (Sandbox Code Playgroud)