简体   繁体   English

Java如果优化

[英]Java If optimization

I do have the following statement: 我有以下声明:

isEnabled = false;
if(foo(arg) && isEnabled) {
 ....
}

public boolean foo(arg) {
  some really long running code
}

Does it make sense to swap the statements inside the if? 在if中交换语句是否有意义?

if(isEnabled && foo(arg)) { ... }

Or does the compiler the optimization for me? 或者编译器是否为我优化?

Note that the two expressions don't have the same behavior if foo() also has side effects . 请注意,如果foo()也有副作用 ,则这两个表达式的行为不同。

If it is manipulating the state of the program, it makes a lot of difference if you always invoke it, or if you invoke it only as a dependency of the value of isEnabled . 如果它正在操作程序的状态,那么如果你总是调用它,或者只是作为isEnabled值的依赖项调用它,它会产生很大的不同。

For example, consider: 例如,考虑:

boolean foo(Object arg) { 
  someLocalVariable = arg;
  //do some calculation and return an answer
}

It matters if you always invoke foo() , or if you invoke it only in the case where isEnabled is turned on, resulting in the following two expressions to be completely different from each other: 如果你总是调用foo() ,或者只有在打开isEnabled的情况下才调用它,这会导致以下两个表达式彼此完全不同,这很重要:

if (isEnabled && foo(arg)) { ...}  //local variable changes only if isEnabled==true
if (foo(arg) && isEnabled) { ...} //local variable always changes

The compiler will not do any optimization in this case. 在这种情况下,编译器不会进行任何优化。

if(isEnabled && foo(arg)) { ... }

Is always the better approach. 始终是更好的方法。

Because i guess you know that when isEnabled is false it will not evaluate foo(arg) . 因为我猜你知道当isEnabled为false时它不会评估foo(arg) And compiler will maintain your sequence of instruction. 编译器将维护您的指令序列。

Does it make sense to swap the statements inside the if? 在if中交换语句是否有意义?

Yes. 是。 && will only evalute the sub-expressions until one is false . &&只会评估子表达式,直到其中一个为false Then the complete exprission will be false , no matter what the other expressions evaluate to. 然后,无论其他表达式评估的是什么,完整的表达都将是false

Since the compiler would have to keep the logic as it is (which includes the order of statements) it won't optimize that. 由于编译器必须保持逻辑原样(包括语句的顺序),因此不会对其进行优化。

Suppose foo() has a side effect which some other part of the code relies on, changing the order might break that. 假设foo()有一个副作用,代码的其他部分依赖于此,改变顺序可能会破坏它。 Of course this isn't good style in most cases but the compiler can't rely on or enforce style so it has to trust the developer here. 当然,在大多数情况下这不是好的风格,但编译器不能依赖或强制执行样式,所以它必须信任开发人员。

Example: 例:

int x = 0;

boolean foo(int arg) {
  x = arg;
  return x > 0;
}

void someMethod(int arg) {
  boolean isEnabled = false;
  if(foo(arg) && isEnabled) {
    //whatever  
  }

  //here you use x, I'll simply print it
  System.out.println("x=" + x);
}

void someOtherMethod(int arg) {
  boolean isEnabled = false;
  if(isEnabled && foo(arg)) {
    //whatever  
  }

  //here you use x, I'll simply print it
  System.out.println("x=" + x);
}

Now calling the methods: 现在调用方法:

someOtherMethod(7); //foo(7) will not be called so x will still be 0
someMethod(5);    

you'll get the output 你会得到输出

x=0  
x=5 

First of all, the Java compiler (which turns java source into bytecode) is pretty dumb . 首先,Java编译器(将java源代码转换为字节码)非常愚蠢 Out of the many optimization techniques known to compiler constructors, just a handful (like constant folding) are implemented by javac. 在编译器构造函数已知的许多优化技术中,javac只实现了一些(如常量折叠)。

Whereas the Java just-in-time compiler does many many more things; 而Java即时编译器可以做很多事情; but even the JIT will not change the order of arguments for you (as that can change the semantics of the underlying program). 但即使是JIT也不会改变你的参数顺序(因为它可以改变底层程序的语义)。

Finally, when thinking about this code, performance should not be the motivation behind you changing it. 最后,在考虑这个代码时, 性能不应该是你改变它的动机。 Instead, you should worry about the semantics too. 相反,你也应该担心语义。 Do you want that foo() is executed (for side effects); 你想要执行foo()(副作用); or maybe do you not want that foo() runs all the time? 或者你可能不希望foo()一直运行?

Of course, "foo()" could be doing many many things; 当然,“foo()”可以做很多事情; and not executing it might gain some performance. 并且不执行它可能会获得一些性能。 But most likely: it will not matter (from a performance perspective). 但最有可能的是:从性能角度来看并不重要。

In other words: stay away from micro-optimisations, see here for backing reasons to that recommendation. 换句话说:远离微观优化,请参阅此处了解该建议的支持原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM