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

标签 java if-statement logical-operators

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

示例:

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

或者这样更快

 if(A||B)
  if(B||C)
   if(C||D)
    ...
     if(N||N+1)
      System.out.println("Hello World");

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

最佳答案

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

在我的测试用例中,嵌套 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);
    }
}

结果

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

原子长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

关于java - 许多 If 语句与长逻辑表达式的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23559526/

相关文章:

language-agnostic - 两个 bool 值的理想 If 语句结构

java - 在哪里可以找到类型安全的不可修改集合实现?

java - 如何在打开的菜单下绘制图像

Java Swing JTextArea 滚动条未显示在内部

java - 如何在静态web项目中更改Intellij运行端口?

c - c 的 if、switch 和 while 条件中的打印语句

java - 谁能解释一下这个 "dead code"的例子吗?

c++ - 在条件之外使用短路运算符是否合法?

c++ - 请从 Accelerated C++ 解释以下内容

Javascript - 是否有更清晰的方式来表达 "if (a && b || !a && !b)"?