繁体   English   中英

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

[英]C++ performance, optimizing compiler, empty function in .cpp

我有一个非常基础的类,将其命名为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

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

编译器可能会优化此代码,如果它在编译时知道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
#if PRINT_DEBUG
#define printDebug _real_print_debug
#else
#define printDebug(...)
#endif

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

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

只是在我的头顶,像:

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

目前,大多数优化都是在编译时完成的。 一些编译器作为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);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM