使用短路评估的好处

Swa*_*ati 10 architecture pipeline

boolean a = false, b = true;
if ( a && b ) { ... };
Run Code Online (Sandbox Code Playgroud)

在大多数语言中,b不会被评估,因为它a是假的,所以a && b不可能是真的.我的问题是,在架构方面,短路会不会更慢?在管道中,您是否只是在等待获得a的结果时停止以确定是否应该评估b?改为使用嵌套ifs会更好吗?这甚至有帮助吗?

此外,有谁知道通常所谓的短路评估?这个问题出现之后我发现我的编程朋友从未听说过短路评估,并表示它不常见,也没有在许多语言中找到,并且管道效率低下.我不确定最后一个,所以问你们大家好!

好吧,我想一个不同的例子或许可以解释我的朋友可能来自哪里.他认为,自从评估如下的声明:

(a) if ( ( a != null ) && ( a.equals(b) ) ) { ... }
Run Code Online (Sandbox Code Playgroud)

会崩溃系统,一个没有短路的架构(从而不允许像上面这样的语句)在处理这样的语句时会更快:

(b) if ( ( a == 4 ) && ( b == 5 ) )
Run Code Online (Sandbox Code Playgroud)

因为如果它不能并行地做(a),它就不能并行地做(b).在这种情况下,允许短路的语言比没有短路的语言慢.

我不知道这是不是真的.

谢谢

sir*_*art 12

如果语句(分支基本上是goto),短路评估将以相同的方式转换为汇编语言中的分支,这意味着它不会比if语句慢.

分支通常不会停止管道,但处理器将猜测分支是否被占用,如果处理器是错误的,则必须清除因管道错误猜测而发生的所有事情.

短路评估也是最常见的名称,并且在大多数语言中以某种形式存在.


Ste*_*sop 10

短路布尔表达式与某些嵌套ifs集完全等效,因此效果与此类似.

如果b没有副作用,它仍然可以与a并行执行(对于任何"并行"值,包括流水线).

如果b具有CPU架构在分支预测失败时无法取消的副作用,那么可能需要延迟,如果双方都被评估,则可能不会出现延迟.因此,如果您发现短路运算符在您的代码中造成性能瓶颈,那么可以看一下,但不值得担心.

但短路用于控制流程,以节省不必要的工作.它在我使用的语言中很常见,例如Perl习语:

open($filename) or die("couldn't open file");
Run Code Online (Sandbox Code Playgroud)

shell成语:

do_something || echo "that failed"
Run Code Online (Sandbox Code Playgroud)

或者C/C++/Java/etc成语:

if ((obj != 0) && (obj->ready)) { do_something; } // not -> in Java of course.
Run Code Online (Sandbox Code Playgroud)

在所有这些情况下,您都需要进行短路,因此仅在LHS规定应该进行RHS评估时才对RHS进行评估.在这种情况下,将性能与替代代码进行比较是没有意义的!


Sho*_*og9 8

老实说,我不担心.测试布尔值真的很快.当第二个表达式有副作用时,短路只会变得有趣/有用:

if ( ConfirmAction() && DestroyAllData() )
   Reboot();
Run Code Online (Sandbox Code Playgroud)

......或取决于第一次测试:

if ( myDodgyVar != null && myDodgyVar.IsActive() )
   DoSomethingWith(myDodgyVar);
Run Code Online (Sandbox Code Playgroud)


Ale*_*roR 5

支持短路的语言:

阿达,埃菲尔铁塔,ALGOL 68,C,C++,C#,Java的,R,二郎,标准ML,使用Javascript,MATLAB,Lisp语言,Lua中,计划,OCaml中,哈斯克尔,帕斯卡尔,Perl中,红宝石,PHP,Python和Smalltalk中,Visual Basic中.净

取自短路评估