调用空类方法会影响性能吗?

时间:2013-03-21 15:55:50

标签: c++ performance visual-studio-2005

Timer.h:

class Timer
{
public:
void start();
void printTimeAndRestart(const char* msg);
};
namespace Timing {    static Timer timer; }

Timer.cpp:

#ifdef DO_TIMING
//implementation
void Timer::start() { ... };
void Timer::printTimeAndRestart(const char* msg) { ... };
#else
//empty - do not do timing
void Timer::start() {};
void Timer::printTimeAndRestart(const char* /*msg*/) {};
#endif

计时器将用于许多不同的文件,如:

Timing::timer.start(); 
... 
Timing::timer.printTimeAndRestart("Operation X took :");

如果应用程序对性能非常敏感且经常调用定时器,那么在未定义DO_TIMING时调用空方法会影响性能吗?什么是实现隔离计时器的更好选择(无需重新编译整个项目以打开/关闭),这在关闭时根本不会影响性能。

到目前为止,我只能想到定义像

这样的宏
#ifdef DO_TIMING 
#define START_TIMING()
Timing::timer.start(); 
#endif
#else
#define START_TIMING()
#endif

并使用它们代替Timing :: timer.start();但这需要重新编译整个代码才能打开/关闭它们......

5 个答案:

答案 0 :(得分:3)

这取决于你如何使用它。如果它是相同的项目/解决方案并且编译器能够进行完整的程序优化,那么它可能是无关紧要的。

如果您使用二进制文件分发代码并且实现不可见,并且编译器无法告诉它为空,则由于调用会产生一些(次要的)开销。

答案 1 :(得分:0)

在调试版本中,这将被调用,并且将具有任何函数调用的整体效果。在优化代码中,编译器通常会省略调用。

根据以下评论。

在调用站点,编译器将无法确定被调用函数无效。如果您的宏也定义了内联的空条件,那么调用站点将能够看到该函数基本上是一个noop。

答案 2 :(得分:0)

如果您想更加确定编译器将优化呼叫,请执行以下操作:

Timer.h:

class Timer
{
  public:
  void start();
  void printTimeAndRestart(const char* msg);
};

namespace Timing {    static Timer timer; }

#ifndef DO_TIMING
inline void Timer::start() {}
inline void printTimeAndRestart(const char*) {}
#endif

Timer.cpp:

#ifdef DO_TIMING
//implementation
void Timer::start() { ... };
void Timer::printTimeAndRestart(const char* msg) { ... };
#endif

答案 3 :(得分:0)

高质量的编译器可能会删除它,但是确保在.h文件中内联空函数更安全:

Timer.h

class Timer
{
public:
  void start();
  void printTimeAndRestart(const char* msg);
};

#ifndef DO_TIMING

inline void Timer::start() {}
inline void printTimeAndRestart(const char* msg) {}

#endif

namespace Timing {    static Timer timer; }

Timer.cpp

#ifdef DO_TIMING

// ...

#endif

不幸的是,这确实意味着你将一个依赖项绑定到标题中,这将导致在打开或关闭时重新编译。

答案 4 :(得分:0)

如果函数被定义为“inline”(即,作为声明它们所属的类的头文件的一部分),则编译器可以避免为空函数生成代码。如果函数在.cpp文件中,编译器必须生成调用函数的代码,因为编译器无法知道函数的作用[除非编译器支持“整个程序优化”]。

我的解决方案是将函数移动到头文件中,而不是使用宏。这是一个更简洁的解决方案,除非编译器绝对是垃圾,否则它应该将其排除为“无代码生成”。