我见过像这样的陈述
if(SomeBoolReturningFunc())
{
//do some stuff
//do some more stuff
}
我想知道在if语句中放置一个函数是否有效,或者是否有更好的方法将它们分开,就像这样
bool AwesomeResult = SomeBoolReturningFunc();
if(AwesomeResult)
{
//do some other, more important stuff
}
...
答案 0 :(得分:26)
我不确定是什么让你认为首先将表达式的结果赋值给变量比评估表达式本身更有效,但它永远不会重要,所以选择增强你的可读性的选项码。如果确实想知道,请查看编译器的输出,看看是否有任何区别。在绝大多数系统中,这可能会产生相同的机器代码。
答案 1 :(得分:7)
无论哪种方式都无关紧要。基本的想法是,无论你命名与否,结果都将存储在一个临时变量中。可读性现在更重要,因为计算机通常如此之快,以至于小调整无关紧要。
答案 2 :(得分:3)
我当然看到if(f()){blah;}产生的代码比bool r = f(); if(r){blah;},但那是多年前的68000。
现在,我肯定会选择更容易调试的代码。与编译器生成的代码相比,您的低效率更有可能是您的算法。
答案 3 :(得分:3)
另外,如果条件处于循环中,完全避免分支可以提供更多的性能。
例如,通过为每个条件案例设置单独的循环,或者通过具有固有地考虑条件的语句(如果不需要,可以通过将项乘以0)
然后你可以通过展开那个循环获得更多
模板化代码可以以“半”干净的方式为此提供很多帮助。
答案 4 :(得分:2)
还有可能
if (bool AwesomeResult = SomeBoolRetuningFunc()) { ... }
:)
IMO,你看到的那种陈述更容易阅读,并且不易出错:
bool result = Foo();
if (result) {
//some stuff
}
bool other_result = Bar();
if (result) { //should be other_result? Hopefully caught by "unused variable" warning...
//more stuff
}
答案 5 :(得分:2)
两种变体通常生成相同的机器代码并且运行完全相同。很少会出现性能差异,即使在这种情况下,它也不会成为瓶颈(这可以转化为在分析之前不会打扰)。
显着的区别在于调试和可读性。使用临时变量,它更容易调试。没有变量,代码就会更短,也许更具可读性。
如果您希望既易于调试又更易于阅读代码,则最好将变量声明为const
:
const bool AwesomeResult = SomeBoolReturningFunc();
if(AwesomeResult)
{
//do some other, more important stuff
}
这样更清楚的是变量永远不会再分配给它,并且它的声明背后没有其他逻辑。
答案 6 :(得分:1)
不考虑任何调试简易性或可读性问题,并且只要在if块中不再使用函数的返回值;在我看来,将返回值赋给变量只会导致额外使用=运算符和存储在堆栈空间中的额外bool变量 - 我可能会进一步推测堆栈空间中的额外变量将导致进一步堆栈的延迟访问(虽然不确定)。
问题是,这些都是小问题,只要编译器上有优化标志,就不会导致效率低下。我考虑的另一种情况是嵌入式系统 - 那么,单个8位变量会造成多大的损害? (我对嵌入式系统有绝对的没有知识,所以也许其他人可以详细说明这个?)
答案 7 :(得分:1)
我似乎记得每行的一个陈述是本书Code Complete的建议,其中有人认为这样的代码更容易理解。使每个语句只做一件事,这样很容易一眼就看出代码中发生了什么。
我个人喜欢在变量中使用返回类型,以便在调试器中更容易检查(甚至更改)。
一个答案表明在生成的代码中观察到了差异。我真诚地怀疑使用优化编译器。
对于多行,在C ++ 11之前的一个缺点是你必须知道变量声明的返回类型。例如,如果返回值从bool更改为int,那么根据所涉及的类型,您可能在局部变量中具有截断值(这可能会导致if故障)。如果使用C ++ 11进行编译,则可以使用auto关键字来处理,如:
auto AwesomeResult = SomeBoolReturningFunc() ;
if ( AwesomeResult )
{
//do some other, more important stuff
}
Stroustrup's C++ 4th edition建议将变量声明放在if语句本身中,如:
if ( auto AwesomeResult = SomeBoolReturningFunc() )
{
//do some other, more important stuff
}
他的论点是,这最大限度地限制了变量的范围。判断调用是否更具可读性(或可调试性)。
答案 8 :(得分:1)
如果SomeBoolReturningFunc()相当慢,并且你能够多次使用AwesomeResult而不是再次调用SomeBoolReturningFunc(),那么AwesomeResult版本会更快。
答案 9 :(得分:1)
将函数放在if语句的内部或外部并不重要。没有性能增益或损失。这是因为编译器将自动在堆栈上为返回值创建一个位置 - 无论您是否明确定义了变量。
答案 10 :(得分:1)
在我完成的性能调整中,只有在清除了一系列重要的性能问题后,才会在循环剃须的最后阶段考虑这个问题。