Performance 嵌套'if'是否会提高性能?

Performance 嵌套'if'是否会提高性能?,performance,optimization,if-statement,conditional-statements,short-circuiting,Performance,Optimization,If Statement,Conditional Statements,Short Circuiting,如果我有此代码: if (isFoo() && isBar()) { ... } 程序将计算第一个条件,然后计算第二个条件,然后确定是通过还是跳过下面的块 但是,如果我嵌套这样的条件: if (isFoo()) if(isBar()) { ... } 现在,它检查第一个条件,如果为false,则不必考虑第二个条件 如果第二个条件(作为一个函数)是一个耗时的内存开销,那么嵌套它似乎更好 这是真的吗?我以前从未见过这样的代码,在第一

如果我有此代码:

if (isFoo() && isBar())
{
    ...
}
程序将计算第一个条件,然后计算第二个条件,然后确定是通过还是跳过下面的块

但是,如果我嵌套这样的条件:

if (isFoo())
    if(isBar())
    {
        ...
    }
现在,它检查第一个条件,如果为false,则不必考虑第二个条件

如果第二个条件(作为一个函数)是一个耗时的内存开销,那么嵌套它似乎更好


这是真的吗?我以前从未见过这样的代码,在第一个示例之后我做了一个假设,但在我看来这是非常可能的。

我相信大多数编译器都会为您进行这种优化。如果&&的第一个条件为false,则第二个条件将不会执行。

所有现代语言都将短路任何AND'ed子句。因此,在您的示例中,如果isFoo()为false,它甚至不必检查isBar(),它将退出if语句

程序将计算第一个条件,然后计算第二个条件

不,不是在大多数现代语言中(例如C、C++)。因为众所周知,如果第一个条件为false,那么
表达式的值不可能是false以外的任何值,因此不计算第二部分。在这两种语言中,标准明确定义了这种优化(称为“短路评估”)。

在C#/C++和许多其他语言中,您有两个逻辑
运算符,实际上:
&
&

&
操作员将评估这两种情况

&&
运算符将只计算第一部分,如果它等于
FALSE
,则跳过表达式的第二部分

这同样适用于逻辑
运算符。有两个运算符:
|
|

|
操作员将评估这两种情况

|
运算符将仅首先求值,如果它等于
TRUE
,则跳过表达式的第二部分

因此,回答您的问题,在您的示例中,您使用的是
&&
,它将作为两个嵌套的
if

[编辑]:好的,要找到使用|和&,就我个人而言,我在最短代码竞赛中使用过它们)的例子并不是那么容易,这才是它们真正有用的地方(不是因为它们比&&和| |)。还考虑下面的例子:

static bool LaunchFirstRocket()
{
    // Launching rocket if all is ok return true, or return false if we failed to launch it.
}

static bool LaunchSecondRocket()
{
    // Launching rocket if all is ok return true, or return false if we failed to launch it.
} 

static void Main(string[] args)
{
    if (LaunchFirstRocket() & LaunchSecondRocket())
    {
        Console.WriteLine("Both rockets have launched successfully!");
    }
}

在这里,我们将强制执行这两种方法,而不管第一种方法的结果如何。如果第一枚火箭失败,我们还想发射第二枚,这是我们的逻辑。是的,有很多其他方法可以编写这样的代码,但这只是一个用于教育目的的例子。正如其他人所指出的,在使用的编译语言(如C和C++)中,两个版本可能编译为完全相同的代码

在一些解释语言中,例如Perl,第二个版本实际上可能比第一个版本稍微慢一点,因为在输入代码块时有少量开销。例如,这个人工基准清楚地显示了差异:

use Benchmark':all';
我的$count=shift | | 10 | 000 | 000;
我们的($foo,$bar,$baz)=(1,1,1);
时间是多少{
'和'=>'如果($foo&&$bar){$baz++;}',
'nested'=>'if($foo){if($bar){$baz++;}}},
});
输出:

Benchmark:为和的10000000次迭代计时,嵌套。。。
和:2个时钟秒(2.41USR+0.00SYS=2.41CPU)@4149377.59/s(n=10000000)
嵌套:4个时钟秒(3.54 usr+0.00 sys=3.54 CPU)@2824858.76/s(n=10000000)

当然,在实践中,这种差异可能是完全不重要的,特别是与使用解释语言的一般开销相比。

这取决于编程语言

大多数现代/流行语言都支持,这意味着程序不计算整个表达式,而是在得到整个表达式的结果后立即停止计算(其他语言已经给出了示例)

但也有例外 我知道的两种不支持短路评估的语言是Microsoft VB(6)和VB.NET

VB6根本不支持它,所以这里的嵌套
If
s If通用优化技术。 而且在表达上

If Not rs Is Nothing And Not rs.EOF

如果
s给出执行错误而
rs
Nothing
,则不使用嵌套

VB.NET
引入了两个新的逻辑运算符,它们支持短路评估

标准的
VB.NET
操作符不支持短路评估,这是新开发人员常见的错误源

优化 在这两种情况下(语言支持和非短路评估),您都可以进行检查 表达式,以便更快地首先求值

因此,与其(如果用户是女性,请使用偶数键登录数据库),不如:

使用(检查是否登录(布尔值),使用偶数键(算术运算符),最后检查数据库中的性别):


请看,这当然不是“语言不可知论”,但大多数语言都会短路布尔值,并且两个结构是相同的。@Williampersell谢谢您的评论,我已经标记了这个问题(希望现在不再有问题)。没有任何and'ed子句。有些和的从句是不会短路的。有些和的表达是不会短路的-circuited@SergeyS看看威廉·珀塞尔的评论,这真的很有趣。有没有一种方法我更愿意使用
&
|
?当您需要它们时,这是一种罕见的情况,但根据我的经验,我有这种情况。我将在我的回答中添加示例更新,看一看,也许这不是最好的示例,但它只是给出一个想法。
&if (db.getUserSex() == FEMALE && userKey % 2 == 0 && userKey % 2 && isUserLogged)
if (isUserLogged && userKey % 2 == 0 && db.getUserSex() == FEMALE)