2017-10-11 134 views
0

一些上下文:高效設計用於可選的分析執行代碼

我具有執行一些計算集約(在車輛路徑問題變異一些分支定界算法)一個C++方法。因此效率在這個規範中是最重要的。 當我測試不同的技巧以達到最佳速度時,我最終實現了一個類StatGatherer,該類在給定的算法運行期間收集信息(即:找到了多少條可行路徑,有多少條有界,有多少條被發現是不可行的。 ..)。代碼如下所示:

void doStuff(const shared_ptr<StatGatherer>& statGatherer = NULL) 
{ 
    //do some stuff 
    ... 

    if (statGatherer != NULL && some unfeasibility condition) 
     statGatherer->countOneFeasiblePath(); 

    //do more stuff 
    ... 

    if (statGatherer != NULL && some bounding criterium on the current path) 
     statGatherer->countOneBoundedPath(); 

    //do more stuff 
    ...  

    if (statGatherer != NULL && a whole path has been found) 
     statGatherer->countOneBoundedPath(); 
    ... 

    //...more information gathering triggered by certain events 
} 

此作品不夠好,但諷刺的是,這種涉及statGatherer「分析」代碼的存在減慢算法不少,如上面的僞代碼被執行數萬數百萬次。即使沒有提供statGatherer並且默認爲null,它仍然比沒有這個代碼慢很多。

因此,我的問題是:是否有一種設計可以實現相同的行爲,但在不需要收集統計信息的情況下,效率並沒有下降,相比之下根本沒有此代碼?

我能想到的每個模板解決方案似乎仍然涉及到像上面那樣的某種運行時檢查,因此更耗時。

非常感謝您的幫助! PS:我在這裏是新來的,所以我歡迎建設性的反饋意見,讓我的問題更清晰。

+0

使用代碼插對剖析。 – user0042

回答

1

StatGatherer內嵌不做任何實現(並通過引用傳遞)類型的函數進行模板化。編譯器將用模擬完全刪除實例化中的虛假調用。

這避免了模擬方法的需求,但需要從原始的if(statGatherer && ...) statGatherer->...(...);是嘲笑指針的替代:具有模板參數是任一StatGatherer*或虛設指針類型:

template<class T> 
struct dummy_ptr { 
    operator T*() const {return nullptr;} 
    T* operator->() const {return nullptr;} 
}; 
+0

是的 - 編譯時做出決定聽起來像是個好主意。我想我不應該鼓勵它,但#ifdef和#define也允許你在編譯時作出決定。 – mcdowella

+0

感謝vm大衛,這似乎是個伎倆。與你所描述的只有不同之處在於,我通過StatGatherer類創建了一個數據成員以避免傳遞它,因爲它實際上是由我的主例程中的子例程調用的。當StatGatherer是虛擬類時,開銷實際上已經消失。 我也很高興聽到一些不需要編寫虛擬代碼的解決方案,只是爲了讓編譯器感到開心。 – GloomyJul