使用来自同一个bool c++的两个if语句的最佳实践

Best practice for having two if statements from the same bool c++

本文关键字:两个 if 语句 最佳 同一个 bool c++      更新时间:2023-10-16

我有一个if语句,[显然]只有在条件为true时才会运行。在这个if语句之后,有一些代码应该始终运行,然后是另一个if语句,它应该在与第一个相同的条件下运行。

中间的代码使用堆栈的特定元素执行操作,两侧的if分别在操作之前和之后对堆栈执行推送/弹出操作。

所以逻辑是这样的:

  1. 我需要推栈吗?是/否
  2. 在堆栈顶部执行操作
  3. 堆栈被推了吗?(如果是,则弹出)

项目1和项目3是相同的条件。

这是我第一次在c++中写的代码

#include <stdio.h>
#include <stdlib.h>
int somefunction(){
    return rand() % 3 + 1; //return a random number from 1 to 3
}
int ret = 0;

//:::::::::::::::::::::::::::::::::::::::
//  Option 1 Start
//:::::::::::::::::::::::::::::::::::::::
int main(){
    bool run = (ret = somefunction()) == 1; //if the return of the function is 1
    run = (run || (ret == 2));              //or the return of the function is 2
    if (run){                               //execute this if block
        //conditional code
        if (ret == 1){
            //more conditional code
        }
    }
        //unconditional code
    if (run){
        //even more conditional code
    }
}
//:::::::::::::::::::::::::::::::::::::::
//  Option 1 End
//:::::::::::::::::::::::::::::::::::::::

写完这篇文章后,我认为这样做可能更有效:

//:::::::::::::::::::::::::::::::::::::::
//  Option 2 Start
//:::::::::::::::::::::::::::::::::::::::
int main(){
    bool run;
    if (run=(((ret = somefunction()) == 1)||ret == 2)){ //if the return of the function is 1 or 2 then execute this if block
        //conditional code
        if (ret == 1){
            //more conditional code
        }
    }
    //unconditional code
    if (run){
        //even more conditional code
    }
}
//:::::::::::::::::::::::::::::::::::::::
//  Option 2 End
//:::::::::::::::::::::::::::::::::::::::

为了可读性,我更喜欢第一种方法,因为它被分成几行,而第二种方法在同一行中有两个赋值(=)和两个比较(=)。我想知道使用第二种方法是否更好(出于效率或可执行文件大小的原因),或者是否有比两者都更好的方法。

在有人说它只会产生几乎不可估量的影响之前,这是一个巨大的循环,必须在1/50秒内运行数千次,所以我想尽可能多地节省时间。

性能不应该是您关心的问题:现代编译器通常足够聪明,可以在任何情况下优化代码。如果代码在做本质上相同的事情,结果将是相同的。

因此,您应该更喜欢可读性更强(因此更易于维护)的变体。

我会写这样的东西:

ret = somefunction();
// I don't know what is the semantics of ret == 1, so let's imagine some
bool operationIsPush = (ret == 1);
bool operationIsOnTop = (ret == 2);
if (operationIsPush || operationIsOnTop)
{
    //conditional code
}
if (operationIsPush)
{
    //more conditional code
}
//unconditional code
if (operationIsPush || operationIsOnTop)
{
    // ...
}

我相信这里的性能不会有什么不同。第一个原因是编译器可能会在每种情况下优化代码。第二种方法是,您只需更改操作发生的位置(如"I do A->B->C or A->C->B"),而不是更改操作量,因此计算量始终相同(1个函数调用、几个==等等)。

然而,考虑到(run=(((ret = somefunction()) == 1)||ret == 2))很难阅读。

正确性比是否将分配布尔的两个操作合并为一个操作更重要(编译器可能无论如何都会这样做)。

对于推/弹出堆栈,您应该使用scopeguard(此处为原始文章)。这将确保,如果某个东西抛出了"无条件位",而你从来没有真正确定过,那么它仍然可以正确运行。否则你会得到一个有趣的惊喜(一堆一堆,或者满溢)。

如果存在可以将"if-else"拆分为不同的巨大循环的情况,会更快

而不是

loop {  if_1  {some work}    if_2 {some other work}   }

你可以

if_1 { loop {work }}    if_2 {loop{same work}}

更极端的是,如果你能拆分最内部的"如果"句子,你可以有10-20个(根据你的情况而定)不同的巨大循环,运行速度快x2x3(如果因为"如果"而慢)