java - 做 !(!a && b) 比 || 效率低吗!乙?

标签 java performance logical-operators

我有一个运行多次并且必须非常高效的寻路算法,所以我想知道我可以做些什么来提高性能。我有一个 if 语句,上面写着:

if (!(n != 1 && map.isCornerObstructed(p)) {
    // Do stuff...
}

在我看来,双重反转比这个逻辑上等效的版本花费的时间稍长:

if (n == 1 || !map.isCornerObstructed(p)) {
    // Do stuff...
}

问题是前者在代码的上下文中更具可读性,所以如果我不知道结果会是什么,我有点不愿意改变它。

一个比另一个更有效率吗?或者 Java 编译器是否足够智能,可以自动优化此类内容?

最佳答案

代码

Set<String> set = new HashSet<String>();
int n = set.size();
Object o = new Object();
if (!(n != 1 && set.contains(o))) {
  System.out.println("Foo");
  // Do stuff...
}

生成字节码

 0  new java.util.HashSet [16]
 3  dup
 4  invokespecial java.util.HashSet() [18]
 7  astore_1 [set]
 8  aload_1 [set]
 9  invokeinterface java.util.Set.size() : int [19] [nargs: 1]
14  istore_2 [n]
15  new java.lang.Object [3]
18  dup
19  invokespecial java.lang.Object() [8]
22  astore_3 [o]
23  iload_2 [n]
24  iconst_1
25  if_icmpeq 38
28  aload_1 [set]
29  aload_3 [o]
30  invokeinterface java.util.Set.contains(java.lang.Object) : boolean [25] [nargs: 2]
35  ifne 46
38  getstatic java.lang.System.out : java.io.PrintStream [29]
41  ldc <String "Foo"> [35]
43  invokevirtual java.io.PrintStream.println(java.lang.String) : void [37]
46  return

代码

Set<String> set = new HashSet<String>();
int n = set.size();
Object o = new Object();
if (n == 1 || !set.contains(o)) {
  System.out.println("Foo");
  // Do stuff...
}

生成字节码

 0  new java.util.HashSet [16]
 3  dup
 4  invokespecial java.util.HashSet() [18]
 7  astore_1 [set]
 8  aload_1 [set]
 9  invokeinterface java.util.Set.size() : int [19] [nargs: 1]
14  istore_2 [n]
15  new java.lang.Object [3]
18  dup
19  invokespecial java.lang.Object() [8]
22  astore_3 [o]
23  iload_2 [n]
24  iconst_1
25  if_icmpeq 38
28  aload_1 [set]
29  aload_3 [o]
30  invokeinterface java.util.Set.contains(java.lang.Object) : boolean [25] [nargs: 2]
35  ifne 46
38  getstatic java.lang.System.out : java.io.PrintStream [29]
41  ldc <String "Foo"> [35]
43  invokevirtual java.io.PrintStream.println(java.lang.String) : void [37]
46  return

完全相同。因此,无论您测量得多么精细,都不会有性能差异根本。编译后的代码完全相同。

(请注意,这样做的原因是 javac 实际上将 if 语句分解为单独的条件测试和分支,因此它实际上为每个条件计算出路径可能性。)

关于java - 做 !(!a && b) 比 || 效率低吗!乙?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10810500/

相关文章:

java - Camel NotifyBuilder 总是返回 false

java - 从 java 到 prolog 断言事实

asp.net - 如何使用或完成意大利面条代码?

ruby-on-rails - Rails 3/Heroku/Memcached - 未命中/未命中、存储/新鲜

c# - 如何将字典的值复制到 .Net 2.0 中的 IList 对象中?

c# - 字符串的按位运算 - 1440 个字符长度

c# - 使用逻辑或对多个属性进行分组

c - 仅使用逻辑运算符确定数字的奇偶校验

java - Jacoco tcpserver 重置转储

java - 我可以使用 EntityManager 生成 .sql 文件而不是写入数据库吗?