1

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

中间的代码是使用堆栈的特定元素执行操作,两边的 ifs 分别在操作之前和之后对堆栈执行 push/pop。

所以逻辑是这样的:

  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 秒内运行数千次,所以我想尽可能多地节省时间。

4

4 回答 4

5

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

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

我会写这样的东西:

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)
{
    // ...
}
于 2012-07-19T11:10:46.800 回答
1

我相信这里的表现不会有任何差异。第一个原因是您的编译器可能会在每种情况下优化代码。第二个是你只是改变了操作发生的地方(比如“我做 A->B->C 或 A->C->B”),而不是操作的数量,所以它总是相同的计算量(1个函数调用,几个==等等)。

但是考虑到这 (run=(((ret = somefunction()) == 1)||ret == 2)) 很难阅读。

于 2012-07-19T11:12:59.523 回答
1

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

对于推送/弹出堆栈,您应该使用范围保护(此处为原始文章)。这将确保如果某些东西抛出了“无条件位”,你永远无法确定,那么它仍然可以正常运行。否则你会得到一个有趣的惊喜(堆叠一个,或者溢出)。

于 2012-07-19T11:13:48.217 回答
0

如果有一种情况可以将“if-else”拆分为不同的大循环,它会更快

而不是

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

你可以

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

更极端的是,如果您可以拆分最内部的“if”句子,则可以有 10-20 个(取决于您的情况)运行 x2 x3 更快的不同的巨大循环(如果由于“if”而变得缓慢)

于 2012-07-19T11:13:34.747 回答