Architecture 使用短路评估的好处

Architecture 使用短路评估的好处,architecture,pipeline,Architecture,Pipeline,在大多数语言中,b不会被计算,因为a为false,所以a&&b不能为true。我的问题是,就架构而言,短路不是更慢吗?在管道中,您是否只是在等待a的结果以确定是否应评估b时暂停?是否改为使用嵌套的ifs更好?这有帮助吗 还有,有人知道短路评估通常被称为什么吗?这个问题是在我发现我的编程朋友从未听说过短路评估,并表示短路评估并不常见,在许多语言中也不常见,而且在管道中效率低下之后出现的。我不确定最后一个,所以问你们 好吧,我想用另一个例子来解释我的朋友可能来自哪里。他认为,由于同时评估了以下陈述:

在大多数语言中,
b
不会被计算,因为
a
为false,所以
a&&b
不能为true。我的问题是,就架构而言,短路不是更慢吗?在管道中,您是否只是在等待a的结果以确定是否应评估b时暂停?是否改为使用嵌套的ifs更好?这有帮助吗

还有,有人知道短路评估通常被称为什么吗?这个问题是在我发现我的编程朋友从未听说过短路评估,并表示短路评估并不常见,在许多语言中也不常见,而且在管道中效率低下之后出现的。我不确定最后一个,所以问你们

好吧,我想用另一个例子来解释我的朋友可能来自哪里。他认为,由于同时评估了以下陈述:

boolean a = false, b = true;
if ( a && b ) { ... };
将使系统崩溃,不存在短路的体系结构(因此不允许使用上述语句)将更快地处理以下语句:

(a) if ( ( a != null ) && ( a.equals(b) ) ) { ... }
因为如果它不能并行地完成(a),它就不能并行地完成(b)。在这种情况下,允许短路的语言比不允许短路的语言慢

我不知道那是不是真的


谢谢

如果不暂停,嵌套的应用程序怎么可能停止?实际上,如果a和b都是变量,而不是有副作用的表达式,那么好的编译器可以并行加载它们。除了增加行数之外,使用更多ifs没有任何好处。真的,这将是编译器最糟糕的事后猜测


它被称为短路评估。

根据上下文,它也可以被称为“保护”


我几乎在我使用过的每一种语言中都看到过这种情况,几乎有十几种语言都有这种情况。

短路求值在汇编语言中被转换成分支的方式与if语句相同(分支基本上是一个goto),这意味着它不会比if语句慢

分支通常不会暂停管道,但处理器会猜测是否执行了分支,如果处理器出错,它将不得不清除所有已发生的事情,因为它从管道中做出了错误的猜测


短路评估也是最常见的名称,在大多数语言中都以某种形式出现。

老实说,我不担心它。测试布尔值非常快。短路仅在第二个表达式有副作用时才变得有趣/有用:

(b) if ( ( a == 4 ) && ( b == 5 ) )
…或取决于第一次测试:

if ( ConfirmAction() && DestroyAllData() )
   Reboot();

我使用的一个有用的短路如下:

if ( myDodgyVar != null && myDodgyVar.IsActive() )
   DoSomethingWith(myDodgyVar);
在我看来,这是非常可读的,并且功能相当好。一般来说,我尽量避免太多嵌套,因为这会导致难看的代码


尽管如此,我的看法是。

大多数语言对布尔表达式进行短路计算。我一直听说它被称为短路评估

问题中的示例是一个非常简单的示例,它实际上没有提供多少性能优势。当表达式的计算复杂时,性能优势就会显现出来

作为一个很好的例子,想象一个游戏程序有如下内容:

if (a != null && a.equals(somevalue)) {
    ... do something.
}

在这种情况下,碰撞检测远比活动检查昂贵。如果系统中有大量非活动对象,那么性能将显著提高

我对流水线一无所知,但短路评估是许多语言的一个共同特征(这也是我所知道的名称)。在C中,&&和其他操作符定义了a,就像;操作员是这样做的,所以我不认为短路评估的效率比使用多个语句要低。

首先,你的朋友错了。短路求值(也称最小求值)在大多数语言中都可用,并且优于并行语言的嵌套ifs(在这种情况下,返回的第一个条件将导致执行继续)


在任何情况下,即使是在一种简单的非并行语言中,我也看不出嵌套的ifs会有多快,因为在计算第一个条件之前,执行会阻塞。

我只听说它是短路。在管道中,下一次执行的操作不取决于if语句的结果吗?如果是这种情况,这将更加优化,因此它不必每次都测试两个值。

短路,或者最小求值只是嵌套ifs的语法糖。 假设它是低效的,或导致失速是一种过早优化的情况。
此时,大多数编译器都足够智能,能够正确解释和优化这些语句。使用这些语句可以大大减少嵌套,从而提高代码可读性,这应该是您的首要目标。

单个线程是连续的,因此如果有两个ifs,第一个ifs当然会在第二个ifs之前进行计算,因此我看不出有什么不同。我使用的条件AND运算符(即&&所称的afaik)比嵌套ifs多得多。如果我想检查一些可能需要一段时间才能评估的东西,我会先做一个简单的测试,然后再做一个更难的测试,然后是条件测试和条件测试

if (someObject.isActive() && someOtherObject.isActive() && CollisionDetection.collides(someObject, someOtherObject) {
  doSomething();
}
看起来和以前没什么不同

a=false;
if(obj.somethingQuickToTest())

a=对象某物slowtotest()

关于短路是否有效,流水线不太可能对性能产生太大影响。在可能产生影响的情况下,只要这些测试没有副作用,就没有什么可以阻止编译器并行测试多个条件。此外,现代CPU有几种机制可用于改进branchy代码的管道性能

嵌套的ifs将具有与短路和短路相同的效果

“短路评估”是最重要的
a = obj.somethingQuickToTest() && obj.somethingSlowToTest();
a = false;
if(obj.somethingQuickToTest())
   a = obj.somethingSlowToTest();
IF A And B THEN
    ...
END IF
IF A AndAlso B THEN
    ...
END IF
If MyObj IsNot Nothing AndAlso MyObj.Value < SomeValue Then
    ....
End If
open($filename) or die("couldn't open file");
do_something || echo "that failed"
if ((obj != 0) && (obj->ready)) { do_something; } // not -> in Java of course.