Java 他在干什么!(!a&;b)效率比a低!B

Java 他在干什么!(!a&;b)效率比a低!B,java,performance,logical-operators,Java,Performance,Logical Operators,我有一个寻路算法,它运行了很多次,必须非常有效,所以我想知道我能做些什么来提高性能。我有一个if声明,其中说: if (!(n != 1 && map.isCornerObstructed(p)) { // Do stuff... } 在我看来,双反转所需的时间比这个逻辑上等效的版本稍长: if (n == 1 || !map.isCornerObstructed(p)) { // Do stuff... } 问题是前者在代码上下文中更具可读性,所以如果我不知

我有一个寻路算法,它运行了很多次,必须非常有效,所以我想知道我能做些什么来提高性能。我有一个if声明,其中说:

if (!(n != 1 && map.isCornerObstructed(p)) {
    // Do stuff...
}
在我看来,双反转所需的时间比这个逻辑上等效的版本稍长:

if (n == 1 || !map.isCornerObstructed(p)) {
    // Do stuff...
}
问题是前者在代码上下文中更具可读性,所以如果我不知道结果会是什么,我就不太愿意更改它


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

请关注优化算法的复杂性,而不是这些微优化


对于这种情况,我看到一个比较(
!=
=
),一个逻辑运算符,一个否定。在n!=1种情况下,逻辑操作的数量相同。在n==1的情况下,第一种情况下的逻辑操作数大于第二种情况。如果有更多的n!=1例,那么可能无关紧要。如果有更多的n==1个案例,那么第二个案例可能会快几分钟。但是由于整个JIT编译器都在工作,我不知道到底发生了什么。微优化可能适用于C/C++代码,但我真的怀疑它对Java的影响。

请关注优化算法的复杂性,而不是这些微优化


对于这种情况,我看到一个比较(
!=
=
),一个逻辑运算符,一个否定。在n!=1种情况下,逻辑操作的数量相同。在n==1的情况下,第一种情况下的逻辑操作数大于第二种情况。如果有更多的n!=1例,那么可能无关紧要。如果有更多的n==1个案例,那么第二个案例可能会快几分钟。但是由于整个JIT编译器都在工作,我不知道到底发生了什么。微优化可能适用于C/C++代码,但我真的怀疑它对Java的影响。

如果你在这里或那里只做过一次,谁在乎呢。任何一个都最多相当于几个cpu周期。

如果你在这里或那里执行一次该语句,谁在乎呢。任何一个都最多相当于几个cpu周期。

我关心的是映射。IScornerObjected(p)调用比任何其他调用都快,布尔逻辑速度快,但方法调用不多

我会选择第二个选项——这似乎是最容易阅读和最有效的


正如评论所指出的,&&和| |短路,因此您需要最简单的测试方法,使用包装反转只是需要执行的另一层。

我在这里关心的是映射。IsCornerObjected(p)调用比任何其他调用都快,布尔逻辑很快,但方法调用不多

我会选择第二个选项——这似乎是最容易阅读和最有效的


正如评论中所指出的,&&和| |短路,因此您需要最简单的测试方法,使用包装反转只是需要执行的另一层。

第二层可能会更优化。 但这取决于你的代码执行了多少次

更具体地说,在第二个选项中:

if (n == 1 || !map.isCornerObstructed(p)) {
// Do stuff...
}
如果n==1为真,java将不会执行!isCornerObstructed(p),n==1比!isCornerObstructed(p),因此您必须以一种方式编写“if”语句,在大多数情况下,第一个更简单的语句会显示答案

如果您怀疑java优化(!(n!=1&&map.isCornerObstructed(p)),您只需编写一个测试用例,
在一个循环中运行每个语句1000000次,并使用System.currentmils计算每个方法的时间成本,这样就可以对第二个进行优化。 但这取决于你的代码执行了多少次

更具体地说,在第二个选项中:

if (n == 1 || !map.isCornerObstructed(p)) {
// Do stuff...
}
如果n==1为true,java将不会执行!map.isCornerObjected(p),并且n==1比!map.isCornerObjected(p)更优化,因此您必须以一种方式编写“if”语句,在大多数情况下,第一条更简单的语句会显示答案

如果您怀疑java优化(!(n!=1&&map.isCornerObstructed(p)),您只需编写一个测试用例, 在一个循环中运行每个语句1000000次,并使用System.currentmils计算每个方法的时间成本,代码就在这里

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...
}
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...
}
Set Set=newhashset();
int n=set.size();
对象o=新对象();
如果(!(n!=1&&set.contains(o))){
System.out.println(“Foo”);
//做些事情。。。
}
生成字节码

 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
 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
0新java.util.HashSet[16]
3次重复
4 invokespecial java.util.HashSet()[18]
7阿斯托雷1[套]
8 aload_1[套]
9 invokeinterface java.util.Set.size():int[19][nargs:1]
14史努比2[n]
15新java.lang.Object[3]
18次重复
19 invokespecial java.lang.Object()[8]
22 astore_3[o]
23 iload_2[n]
24 iconst_1
25如果icmpeq 38
28 aload_1[套]
29 aload_3[o]
30 invokeinterface java.util.Set.contains(java.lang.Object):布尔[25][nargs:2]
35 ifne 46
38 getstatic java.lang.System.out:java.io.PrintStream[29]
41最不发达国家[35]
43 invokevirtual java.io.PrintStream.println(java.lang.String):void[37]
46返回
代码

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...
}
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...
}
Set Set=newhashset();
int n=set.size();
对象o=新对象();
如果(n==1 | |!集合包含(o)){
System.out.println(“Foo”);
//做些事情。。。
}
生成字节码

 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
 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
0新java.util.HashSet[16]
3次重复
4 invokespecial java.util.HashSet()[18]
7阿斯托雷1[套]
8 aload_1[套]
9 invokeinterface java.util.Set.size():int[19][nargs:1]
14史努比2[n]
15新java.lang.Object[3]
18次重复
19 invokespecial java.lang.Object()[8]
22阿斯特3[o]
23 iload_2[n]
24 iconst_1
25如果icmpeq 38
28 aload_1[套]
29艾尔