C ++性能,优化编译器,.cpp中的空函数

时间:2010-05-04 08:32:54

标签: c++ compiler-optimization

我有一个非常基础的类,将其命名为Basic,几乎用于更大项目中的所有其他文件。在某些情况下,需要调试输出,但在发布模式下,不应该启用它并且是NOOP。

目前标题中有一个定义,可根据设置打开或关闭makro。关闭时,这肯定是一个NOOP。我想知道,如果我有以下代码,如果编译器(MSVS / gcc)能够优化函数调用,那么它又是一个NOOP。 (通过这样做,交换机可以在.cpp中,切换速度会快得多,编译/链接时间也会快。)

--Header--
void printDebug(const Basic* p);

class Basic {
   Basic() {
      simpleSetupCode;

      // this should be a NOOP in release, 
      // but constructor could be inlined
      printDebug(this);
   }
};
--Source--
// PRINT_DEBUG defined somewhere else or here
#if PRINT_DEBUG
void printDebug(const Basic* p) {
   // Lengthy debug print
}
#else
void printDebug(const Basic* p) {}
#endif

5 个答案:

答案 0 :(得分:2)

与所有这样的问题一样,答案是 - 如果它对你真的很重要,试试方法并检查发出的汇编语言。

答案 1 :(得分:1)

编译器可能会优化此代码,如果它在编译时知道printDebug函数的实现。如果printDebug位于另一个对象模块中,则可能只使用链接器使用整个程序优化来优化。但是测试它的唯一方法是读取编译器生成的汇编代码。 如果您已经有PRINT_DEBUG宏,则可以按照定义TRACE的方式对其进行扩展:

#define PRINT_DEBUG    // optional
#ifdef PRINT_DEBUG
#define PRINT_DEBUG_CALL(p) printDebug(p)
#else
#define PRINT_DEBUG_CALL(p)
#endif


void printDebug(const Basic* p);

class Basic {
   Basic() {
      simpleSetupCode;

      // this should be a NOOP in release, 
      // but constructor could be inlined
      PRINT_DEBUG_CALL(this);
   }
};
--Source--
// PRINT_DEBUG defined somewhere else or here
#if PRINT_DEBUG
void printDebug(const Basic* p) {
   // Lengthy debug print
}
#endif

答案 2 :(得分:1)

#if PRINT_DEBUG
#define printDebug _real_print_debug
#else
#define printDebug(...)
#endif

这样预处理器将在它到达编译器之前删除所有调试代码。

答案 3 :(得分:0)

错误,为什么不以不同的方式使用预处理器宏?

仅仅是我的头脑,如:

  #define DEBUG_TRACE(p)
  #ifdef PRINT_DEBUG
    printDebug(p);
  #else
    ;
  #endif

答案 4 :(得分:0)

目前,大多数优化都是在编译时完成的。某些编译器LLVM能够在链接时进行优化。这是一个非常有趣的想法。我建议你看看。

等待这些优化,您可以做的是以下内容。定义一个宏,使您可以根据是否定义DEBUG来包含以下语句。

#ifdef DEBUG
#define IF_DEBUG (false) {} else
#else
#define IF_DEBUG 
#endif

您可以像这样使用它

   Basic() {
      simpleSetupCode;

      // this should be a NOOP in release, 
      // but constructor could be inlined
      IF_DEBUG printDebug(this);
   }

已经比

更具可读性
   Basic() {
      simpleSetupCode;

      // this should be a NOOP in release, 
      // but constructor could be inlined
#if DEBUG
      printDebug(this);
#endif
   }

请注意,您可以将其用作关键字

IF_DEBUG {
   printDebug(this);
   printDebug(thas);
}