2013-03-21 115 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文件中,編譯器必須生成調用該函數的代碼,因爲編譯器無法知道函數的作用[除非編譯器支持「整個程序優化」]。

我的解決方案是將函數移動到頭文件中,而不是使用宏。這是一個更好的解決方案,除非編譯器是絕對垃圾,它應該將其排除爲「無代碼生成」。

相關問題