性能许多 If 语句与长逻辑表达式

Jar*_*ran 5 java if-statement logical-operators

如果我有一个很长的逻辑表达式,将它拆分为许多 if 语句或使用长逻辑表达式是否重要?

例子:

if((A||B)&&(B||C)&&(C||D)&&.....(N||N+1))
      System.out.println("Hello World");
Run Code Online (Sandbox Code Playgroud)

或者这更快

 if(A||B)
  if(B||C)
   if(C||D)
    ...
     if(N||N+1)
      System.out.println("Hello World");
Run Code Online (Sandbox Code Playgroud)

我认为长表达式更快,但许多 if 可能更好读。但我不确定,许多 if 语句是否可行?

aal*_*lku 3

编辑:这是错误的,请参阅下面我的编辑

在我的测试用例中,嵌套 if 更快。我不知道为什么。我预计情况恰恰相反。也许我测试错了。

测试用例

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;

public class Test {
    private static final int RUN_TIMES = 100000000;
    private static final int HEATUP_TIMES = 100000;
    private static final int RESET_EVERY = 1000;

    public static void main(String[] args) {
        Test instance = new Test();
        instance.doTest();
    }

    private long a;
    private long b;
    private long c;
    private long d;
    private long e;
    private long f;
    private AtomicLong n;

    private void doTest() {
        Runnable t1 = new Runnable() {
            public void run() {
                if (
                        (a > b || a > c)
                        && (a > d || b > d) 
                        && (c > e || e > f)
                        && (f > a || f > b) 
                        && (f > e || f > a)
                        && (a > f || f > d) 
                        && (d > e || e > d)
                        && (f > e || f > a) 
                        && (f > b || f > a)) {
                    n.incrementAndGet();
                }
            }

            public String toString() {
                return "task1";
            }
        };
        Runnable t2 = new Runnable() {
            public void run() {
                if (a > b || a > c)
                    if (a > d || b > d)
                        if (c > e || e > f)
                            if (f > a || f > b)
                                if ((f > e || f > a))
                                    if ((a > f || f > d))
                                        if ((d > e || e > d))
                                            if ((f > e || f > a))
                                                n.incrementAndGet();
            }
            public String toString() {
                return "task2";
            }
        };

        List<Runnable> tasks = Arrays.asList(t1, t2, t1, t2, t1, t2, t1, t2, t1, t2);
        for (Runnable r: tasks) {
            benchmark(r);
        }
    }

    private void reset() {
        java.util.Random rnd = new java.util.Random();
        this.a = rnd.nextLong();
        this.b = rnd.nextLong();
        this.c = rnd.nextLong();
        this.d = rnd.nextLong();
        this.e = rnd.nextLong();
        this.f = rnd.nextLong();
    }

    private void benchmark(Runnable t) {
        n = new AtomicLong();
        reset();
        for (int i = 0; i < HEATUP_TIMES; i++) {
            t.run();
        }
        long t0 = System.nanoTime();
        int r = 0;
        for (int i = 0; i < RUN_TIMES; i++) {
            if (r == 0) {
                reset();
                r = RESET_EVERY + 1;
            }
            r--;
            t.run();
        }
        long t1 = System.nanoTime();
        System.out.println(String.format("Task %s was run %d times in %.3f ms",
                t, RUN_TIMES, (t1 - t0) / 1000000d));
        System.out.println("n = " + n);
    }
}
Run Code Online (Sandbox Code Playgroud)

结果

Task task1 was run 100000000 times in 753,292 ms
n = 12666654
Task task2 was run 100000000 times in 491,695 ms
n = 12359347
Task task1 was run 100000000 times in 663,144 ms
n = 12530518
Task task2 was run 100000000 times in 499,428 ms
n = 12567555
Task task1 was run 100000000 times in 740,334 ms
n = 12504492
Task task2 was run 100000000 times in 424,854 ms
n = 12379367
Task task1 was run 100000000 times in 721,993 ms
n = 12541529
Task task2 was run 100000000 times in 430,007 ms
n = 12647635
Task task1 was run 100000000 times in 719,680 ms
n = 12598586
Task task2 was run 100000000 times in 432,019 ms
n = 12581569
Run Code Online (Sandbox Code Playgroud)

原子长n是为了测试我没有弄错一个条件,并且当条件满足时有事情要做。

接受后编辑

正如 TheOtherDude 指出的那样,第二次测试存在缺失条件。修复结果完全不同的问题。现在两个测试花费相同的时间。

Task task1 was run 100000000 times in 907,538 ms
n = 12401389
Task task2 was run 100000000 times in 941,928 ms
n = 12325413
Task task1 was run 100000000 times in 850,497 ms
n = 12417405
Task task2 was run 100000000 times in 873,328 ms
n = 12571559
Task task1 was run 100000000 times in 840,028 ms
n = 12538526
Task task2 was run 100000000 times in 865,157 ms
n = 12461449
Task task1 was run 100000000 times in 860,125 ms
n = 12252240
Task task2 was run 100000000 times in 862,829 ms
n = 12350338
Task task1 was run 100000000 times in 866,317 ms
n = 12597585
Task task2 was run 100000000 times in 866,483 ms
n = 12538526
Run Code Online (Sandbox Code Playgroud)