2012-07-19 47 views
1

我有一个if语句[显然]只有在条件为真时才运行。在这个if语句之后,有一些代码应该总是运行,之后是另一个if语句,它应该在与第一个语句相同的条件下运行。有两个如果语句来自同一个布尔C++的最佳做法

中间的代码使用堆栈中的特定元素执行操作,两边的if分别在操作前后执行堆栈上的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秒内运行数千次,所以我想尽可能节省时间。

回答

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) 
{ 
    // ... 
} 
+2

+1,直到剖析器这样说,这不是问题。 – zoul 2012-07-19 11:12:22

+0

我明白你的意思,但不一定是“如果IsPush”第一,然后“如果IsPush || IsOnTop”,然后另一个“如果IsPush”? 谢谢。 – DanJAB 2012-07-19 11:27:00

+0

@DanJAB:你是对的,我已经调整了代码 – Vlad 2012-07-19 11:50:11

1

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

但是认为这个 (run=(((ret = somefunction()) == 1)||ret == 2)) 是很难看。

0

如果那里有,你可以分割的情况 “的if-else”,以独特的巨大的循环,它会更快

而不是

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

可以

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

更非常,如果你能分裂最内在的“如果”句子,你可以有10-20(根据你的情况)独特的巨大循环,运行x2 x3更快(如果它缓慢,因为“if”)

+0

这个麻烦,就是每个if_1在执行时必须有一个if_2在下一个if_1被调用之前执行(在我的情况下) – DanJAB 2012-07-19 11:24:39

+0

所以你说全部if是依赖的 – 2012-07-19 11:25:51

+0

那么,因为它是在一个堆栈上,循环的每一次迭代必须是这样的:[如果]推,操作,[如果]流行,下一个......所以它不能很多“[如果]推“,然后很多操作,然后很多”[如果]弹出“ – DanJAB 2012-07-19 11:30:04

1

正确性比将两个操作分配给一个布尔(编译器可能会这样做)更重要。

对于推送/弹出堆栈,您应该使用scopeguard(原始文章here)。这将确保如果某些东西抛出“无条件位”,而您确实无法确定,那么它仍然可以正常运行。否则,你会感到有趣的惊喜(由一个堆积或溢出)。