我理解下面的差异(至少对Java来说):
if( true || false ) // short-circuiting boolean operator
if( true | false ) // non-short-circuiting boolean operator
但我的问题是,在处理布尔表达式时是否有任何理由使用非短路运算符?是否有一些性能优势或使用不会被视为不良练?
答案 0 :(得分:9)
您可能想要使用非短路操作符的一个原因是,如果您某种程度上取决于函数的副作用。例如。
boolean isBig(String text) {
System.out.println(text);
return text.length() > 10;
}
...
if( isBig(string1) || isBig(string2) ){
...
}
如果您不关心println
是否已执行,那么您应该使用上述的短路操作。但是,如果您希望始终打印两个字符串(因此取决于副作用),则需要使用非短路操作符。
实际上,您几乎总是希望使用短路运营商。依赖于表达式中的副作用通常是糟糕的编程习惯。
一个例外是非常低级别或对性能敏感的代码。短路运算符可能稍微慢一点,因为它们会导致程序执行中的分支。同样使用按位运算符允许您作为单个整数运算执行32或64个并行布尔运算,这非常快。
答案 1 :(得分:8)
如果您的代码对性能足够敏感且操作足够便宜,则使用非短路可能会更快。这是因为使用||
涉及执行分支,并且分支预测未命中可能非常昂贵。其中|
执行计算并检查变量可以更快,避免分支预测错过。
注意:这是一种微观优化,除非被多次调用,否则很少会发现差异。
答案 2 :(得分:5)
short-circuit
,意味着如果没有必要,他们不评估右侧。
例如,如果&&
左侧是假的,则无需评估右侧的一侧。换句话说,||
如果保持原样,则无需评估右手侧。{/ p>
non-short
总是评估双方。
显然,short-circuit
运营商有一个好处。
非短的好处,可以在这里找到答案。Are there good uses for non-short-circuiting logical (boolean) operators in Java/Scala?
也考虑这个例子
while (status){ // status is boolean value
if(!a | result){// a and result are boolean value
result=getResult(); // result can change time to time
}
}
我们现在需要检查双方。
答案 3 :(得分:5)
我的问题更侧重于找到使用|的好处什么时候只处理布尔值
考虑以下案例
while ( !credentialvalid() | (loginAttempts++ < MAX) ) {
// tell something to user.
}
在这种情况下需要|
因为我必须增加尝试次数:)
答案 4 :(得分:4)
只有你不想使用非短路操作符的地方才是你想要执行第二个语句,这通常不应该是条件语句中的情况
否,没有非短路性能,但短路绝对有好处
答案 5 :(得分:2)
如果您使用,
if(true || /*someStatementHere*/)
然后整个if
块将为真,因为第一个条件为真所以它不需要检查另一个
简单地说,如果第一个条件在短路运算符的情况下给出结果,则不会评估右侧操作数
答案 6 :(得分:2)
第三个陈述
if( 10 | 11 ) // bitwise operator
将创建编译错误。只有布尔值可以放在if语句中。
如果您使用的是像Eclipse这样的IDE,它会自动显示第二个表达式,即在||之后作为短路布尔运算符的死代码。
答案 7 :(得分:2)
对于简单的布尔表达式,|
有时比||
更快。有时你想要统一评估表达式(就像索引值中有++
一样。
您不能意外地“混合”布尔|
和按位|
,因为您无法混合布尔和整数操作数。但是你可以(当然)意外地使用|
来表示你想要使用||
。只是感谢它不是C,你不小心使用=
代替==
。
答案 8 :(得分:0)
我不知道为什么所有人都说按位运算只能对布尔操作数进行运算。 我告诉您按位运算符可对操作数类型进行操作,并返回与每个操作数相同的值类型。仅出于理解的目的,将按位运算符视为数学“ +”运算符,可以将两个数字相加。按位的情况也一样。
if(10 | 11)将不会给出编译错误。如果结果为0,则为false,否则为true。
BITWISE运算符不会短路,因为按位运算总是需要2个操作数才能执行。请注意按位使用OPERANDS而不是Boolean_CONDITIONs
语法:
for bitwise : (operand_1) bitwise_operator (operand_2)
for example: ( 2 ) | ( 3 )
for LOGICAL : (Boolean_condition_1) LOGICAL_operator (Boolean_condition_2)
for example: ( true ) || ( false )