2013-03-21 38 views
2

Timer.h:调用空类方法是否会影响性能?

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

Timer.cpp:

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

如果应用程序是非常敏感的性能和:

#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 

计时器会在许多不同的文件等中定时器经常被调用,当DO_TIMING未定义时会调用空方法会影响性能?什么是实现隔离定时器的更好选择(无需重新编译整个项目来打开/关闭),关闭时不会影响性能。

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

#ifdef DO_TIMING 
#define START_TIMING() 
Timing::timer.start(); 
#endif 
#else 
#define START_TIMING() 
#endif 

,并使用他们,而不是定时:: timer.start的();但这需要重新编译整个代码将其打开/关闭...

+0

你尝试过吗? – Default 2013-03-21 15:56:34

+0

还没有 - 在执行它的过程中,如上所述,但我张贴看看有什么其他的设计方案/如果有可能通过查看设计来分辨性能是否会立即受到影响 – 2013-03-21 15:59:46

回答

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 

不幸的是这并不意味着你绑的依赖到,这将导致重新编译,当它开启或关闭标题。

0

在调试版本,这将被调用,会不会有什么函数调用的整体效果。在一般优化的代码中,编译器将省略该调用。

按照下面的评论。

在调用点,编译器将不能够确定的是,所谓的功能没有影响。如果您的宏也定义了内联的空白条件,那么调用站点将能够看到该函数本质上是一个noop。

+3

... *通常* 。 :) – 2013-03-21 15:57:53

+1

编译器如何能够省略呼叫?该定义不在同一个TU中,我不会假定LTO。 – delnan 2013-03-21 15:58:02

+0

它可以确定任何空函数都没有效果,那里只是没有调用它。它类似于编译器在优化时可以将函数优化为内联。 – rerun 2013-03-21 15:59:40

3

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

如果你发布的代码瓦特/二进制文件和执行是不可见的,而编译器无法分辨它是空的,会有一些(未成年人)的开销,由于呼叫。

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 
+0

是的......这会增加更多的确定性(对于某些确定性的定义)。尽管当代码库中任何位置添加任意'#define'都可能会导致这样的情况发生时,我会得到heebie-jeebies。 (无可否认,提问者发明'#define') – 2013-03-21 16:05:11

0

如果功能被定义的“内联”(即,作为declareing它们属于类的头文件的一部分),然后编译程序可避免在空函数生成代码。如果函数在a中。cpp文件中,编译器必须生成调用该函数的代码,因为编译器无法知道函数的作用[除非编译器支持“整个程序优化”]。

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

相关问题