如果我有一个很长的逻辑表达式,将它拆分为多个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");
我认为长表达式更快但许多ifs可能更好阅读。 但我不确定,许多if语句是否切实可行?
答案 0 :(得分:2)
编辑:这是错的,请看下面的编辑
在我的测试用例中,嵌套ifs更快。我不知道为什么。我的预料相反。也许我测试错了。
测试用例
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
答案 1 :(得分:2)
好的,这个问题已经过时了,但我觉得还是值得回答。
任务2缺少一个条件,任务1正在执行。它是最后一个:
&安培;&安培; (f> b || f> a)){
这可能有助于任务2的速度优势。您应该更正并再次测量。
看看OldCurmudgeon给出的第三个选项的速度会很有趣。
另一件事。您会看到执行时间的随机分布。如果执行时间的差异具有统计显着性,那么检查是明智的。
TheOtherDude
答案 2 :(得分:1)
当有可衡量的显着优势时,您应该永远牺牲简单性以获得运行时性能。这里显然没有可衡量的好处,或者你不会问这个问题。
当其他所有方法都失败时 - 尝试简单。
您的选择都不简单 - 尝试其他方法。
public boolean goodToGo(boolean... flags) {
boolean good = true;
for ( int i = 0; i < flags.length - 1 && good; i++ ) {
good &= flags[i] || flags[i+1];
}
return good;
}
public void test() {
if ( goodToGo(true, true, false, true, false, false)) {
System.out.println("Hello");
}
}