Lui*_*ano 48 java optimization
我想知道Java中的一些情况(或更一般地说:在编程中),当布尔表达式中首选使用unconditional AND(&)而不是条件版本(&&)时.
我知道它们是如何工作的,但我不能考虑使用单一的情况&是值得的.
Lou*_*man 60
我已经在现实生活中发现了表达式的两面都非常便宜的情况,所以它削减了一两秒或两个以避免分支并使用无条件&而不是&&.(但这些是非常高性能的数学工具;我几乎从不在其他代码中使用它,如果没有详尽的基准测试来证明它更好,我也不会这样做.)
(举一个具体的例子,x > 0将是超级廉价和无副作用.为什么要冒险分支错误预测,以避免测试会变得如此便宜?当然,因为它是boolean最终结果将被使用无论如何在一个分支,但if (x >= 0 && x <= 10)涉及两个分支,if (x >= 0 & x <= 10)只涉及一个.)
ass*_*ias 20
唯一不同的是,&&和||一旦它被称为停止评价.例如:
if (a != null && a.get() != null)
Run Code Online (Sandbox Code Playgroud)
适用于&&,但&如果a为null,则可能会得到NullPointerException.
我可以考虑你想要使用的唯一情况&是,如果第二个操作数有副作用,例如(可能不是最好的例子,但你明白了):
public static void main(String[] args) {
int i = 1;
if (i == 0 & ++i != 2) {
}
System.out.println(i); //2
i = 1;
if (i == 0 && ++i != 2) {
}
System.out.println(i); //1
}
Run Code Online (Sandbox Code Playgroud)
但是,这看起来像臭臭的代码(在这两种情况下).
小智 15
&&允许jvm进行短路评估.也就是说,如果第一个参数为false,那么它不需要费心检查第二个参数.
一个单一的&将运行双方无论如何.
所以,作为一个人为的例子,你可能会:
if (account.isAllowed() & logAccountAndCheckFlag(account))
// Do something
Run Code Online (Sandbox Code Playgroud)
在该示例中,您可能始终要记录帐户所有者尝试执行某些操作的事实.
我不认为我曾经使用过单一的商业编程.
输入验证是一种可能的情况.您通常希望在一次传递中将表单中的所有错误报告给用户,而不是在第一次传递之后停止,并强制他们重复单击提交,每次只收到一个错误:
public boolean validateField(string userInput, string paramName) {
bool valid;
//do validation
if (valid) {
//updates UI to remove error indicator (if present)
reportValid(paramName);
} else {
//updates UI to indicate a problem (color change, error icon, etc)
reportInvalid(paramName);
}
}
public boolean validateAllInput(...) {
boolean valid = true;
valid = valid & validateField(userInput1, paramName1);
valid = valid & validateField(userInput2, paramName2);
valid = valid & validateField(userInput3, paramName3);
valid = valid & validateField(userInput4, paramName4);
valid = valid & validateField(userInput5, paramName5);
return valid;
}
public void onSubmit() {
if (validateAllInput(...)) {
//go to next page of wizard, update database, etc
processUserInput(userInput1, userInput2, ... );
}
}
public void onInput1Changed() {
validateField(input1.Text, paramName1);
}
public void onInput2Changed() {
validateField(input2.Text, paramName2);
}
...
Run Code Online (Sandbox Code Playgroud)
当然,你可以validateAllInput()通过重构if (valid) { reportValid() ...逻辑来避免短路评估的需要validateField(); 但是每次调用validateField()时你都需要调用提取的代码; 至少为方法调用添加10行.一如既往,这是一种权衡取舍最适合您的情况.
如果表达式是微不足道的,您可以通过使用&或者|您正在阻止分支来进行微优化.即.
if(a && b) { }
if(!(a || b)) { }
Run Code Online (Sandbox Code Playgroud)
是相同的
if (a) if (b) { }
if (!a) if (!b) { }
Run Code Online (Sandbox Code Playgroud)
它有两个地方可以发生分支.
但是使用无条件&或者|,只能有一个分支.
这有用与否有很大程度上取决于代码的作用.
如果你使用它,我会对它进行评论,以便明确说明为什么要这样做.
单个&没有任何具体用途,但您可以考虑以下情况.
if (x > 0 & someMethod(...))
{
// code...
}
Run Code Online (Sandbox Code Playgroud)
考虑这someMethod()是做一些操作,它将修改实例变量或做一些会在以后的处理中影响行为的操作.
因此,在这种情况下,如果您使用&&运算符并且第一个条件失败,它将永远不会进入someMethod().在这种情况下,单个&运算符就足够了.