C++ c++;尝试通过替换测试来优化代码

C++ c++;尝试通过替换测试来优化代码,c++,optimization,C++,Optimization,我正在看别人写的代码,它有很多调试部分,类型如下 if(0) { code } 或if(1){code} 或if(false){code} 甚至还有 #if(0) #endif (虽然没有变成灰色——我想应该是这样的) 我想知道,如果我用一些\if 0(或\ifdef\u DEBUG)替换这些代码,是否可以优化代码或者——这不会有什么区别吗 我认为这可能会有所帮助,因为我已经看到这些部分中的代码变灰了——我认为这些代码已经从发布的可执行文件中删除了。。。因此,让它更快。这是真的吗 我想到的代

我正在看别人写的代码,它有很多调试部分,类型如下

if(0) { code }
if(1){code}

if(false){code}

甚至还有

#if(0)
#endif
(虽然没有变成灰色——我想应该是这样的)

我想知道,如果我用一些
\if 0
(或
\ifdef\u DEBUG
)替换这些代码,是否可以优化代码或者——这不会有什么区别吗

我认为这可能会有所帮助,因为我已经看到这些部分中的代码变灰了——我认为这些代码已经从发布的可执行文件中删除了。。。因此,让它更快。这是真的吗

我想到的代码是在函数中,可以多次调用

编辑:我所指的代码正在运行数百万次。我知道if(0)的内容将被忽略

我还意识到通过将测试从0切换到1,可以轻松调试问题的好处

我的问题是,如果(0)不增加开销,我会增加数百万次测试。。。我正试图找出哪些因素可以使这段代码花费更少的时间

这是真的(取决于构建设置和预处理器)

将调试代码放入
#ifdef_debug
(或类似)是将这些代码完全排除在发布版本之外的标准方法。通常调试版本定义它,而发布版本不定义它


通常,如果给定适当的优化标志,编译器也应该删除代码,例如
if(0)
,但这会给编译器和程序员带来额外的工作(现在您必须全部更改它们!)。我肯定会把这个问题留给预处理器。

如果在编译时放置在这些IFs中的表达式是常量且可确定的,那么您几乎可以肯定编译器已经为您从代码中删除了它们

当然,如果您在调试模式下编译,和/或如果您将优化级别设置为零,那么编译器可能会跳过该选项并保留这些测试-但是如果使用纯零/一/真/假值,则不太可能

对于编译时常量分支,您可以确保编译器删除了死分支

它甚至可以删除复杂的情况,如:

const int x = 5;

if( 3 * x * x < 10 ) // ~ 75 < 10
{
    doBlah(); // skipped
}
const int x=5;
如果(3*x*x<10)/~75<10
{
doBlah();//跳过
}
但是,如果X处没有“const”标记,表达式的值可能在编译时无法确定,并且可能会“泄漏”到实际的最终产品中

此外,以下代码中表达式的值不一定是编译时常量:

const int x = aFunction();

if( 3 * x * x < 10 ) // ~ 75 < 10
{
    doBlah(); // skipped
}
const int x=a函数();
如果(3*x*x<10)/~75<10
{
doBlah();//跳过
}
X是一个常量,但它是用函数中的值初始化的。在编译时,X很可能是不可确定的。在运行时,该函数可以返回任何值*),因此编译器必须假设X是未知的

因此,如果有可能,请使用预处理器。在琐碎的情况下,这不会有多大作用,因为编译器已经知道了这一点。但是案例并不总是琐碎的,你会经常注意到vrey的变化。当优化器无法推断出值时,它会留下代码,即使代码已经死了。另一方面,预处理器保证在编译和优化之前删除禁用的部分。此外,使用预处理器这样做至少会加快编译速度:编译器/优化器不必跟踪常量/计算/检查分支等


*)可以编写一个方法/函数,该方法/函数的返回值在编译和优化阶段实际上是可确定的:如果该函数很简单,并且是内联的,则其结果值可能会与一些分支一起优化。。但是,即使您可以在某种程度上依赖于删除if-0子句,您也不能如此依赖于内联。

如果在
if(0)
块中有代码,编译器生成的代码将与任何合理的编译器上都没有的代码相同。仍将检查代码是否存在编译时错误。(假设里面没有任何跳转标签或其他奇怪的东西。)


如果在
If(1)
块中有代码,编译器生成的代码将与大括号中的代码相同。这是一种给代码块赋予其自身作用域的常见方法,以便在需要的地方销毁局部变量


如果您
ifdef
out代码,那么编译器将完全忽略它。代码可能完全是胡说八道,包含语法错误,或者其他任何东西,编译器不会在意。

你是对的。如果使用
#define DEBUG 0
进行编译,那么实际上将在编译时删除所有
#If DEBUG
块。因此,代码会少得多,运行速度也会更快

只需确保在发布时进行
#定义调试0
后发布代码即可

一个好的优化编译器(GCC,MSVC)将从代码中完全删除
if(0)
if(1)
。。。翻译成机器码不会测试这些条件

通常情况下,
#如果使用0删除代码,同时仍保留代码-例如,为了方便与选项进行比较,我有时会:

#if 1
   some sort of code 
#else
   some other code
#endif
这样,我就可以在两种选择之间快速切换

在这种情况下,预处理器只会在代码中留下两个选项中的一个

if(0)
if(1)
的结构类似-编译器将几乎删除if,对于0,还将删除if语句的其余部分

我认为将此类内容保留在“已完成”的代码中是相当草率的,但这对于调试/开发非常有用if (1) { fast_function(); } else { slower_function(); }