2015-11-20 24 views
0

我在我的代碼中對三個場景進行基準測試,其中我想優化一個if語句(該值在運行時只設置一次,然後檢查數百萬次)我評估的三種方法是如下所示if/else優化測試結果ambigious

1. A template bool binded at compile time 
    2. A static bool initialized on first call 
    3. A bool member variable which gets initialized at construction 

結果有點不直觀,即模板版本需要相同的時間量,但靜態成員變量方法更快。有人能解釋爲什麼嗎?

結果(上多次運行一致)

elapsed time: 0.230933 4501s 
elapsed time: 0.212918 4501s 
elapsed time: 0.230512 4501s 

示例代碼是在這裏

#ifndef TEST_H_ 
#define TEST_H_ 

#include <math.h> 
#include <iostream> 

template<bool Condition> 
class Test { 
public: 
    Test() : 
     signal_(0.0), condition_(false), max_truncation_(12000.00) { 
    } 
    ~Test() { 
    } 

    void CalculateTestingTemplate(double& i); 

    void CalculateTestingStatic(double& i); 
    void CalculateTestingMemberVariable(double& i); 

private: 
    double signal_; 
    double condition_; 

    double max_truncation_; 
}; 

template<bool Condition> 
void Test<Condition>::CalculateTestingTemplate(double& i) { 
    i++; 

    if (Condition) { 
     if (fabs(i) > max_truncation_) { 
      i = 0; 
     } 
    } 

    if (Condition) { 
     if (fabs(i) > max_truncation_) { 
      i = 0; 
     } 
    } 

    if (fabs(i) > max_truncation_) { 
     i = 0; 
    } 
}; 

template<bool Condition> 
void Test<Condition>::CalculateTestingStatic(double& i) { 
    i++; 
    static bool condition = condition_; 
    if (condition) { 
     if (fabs(i) > max_truncation_) { 
      i = 0; 
     } 
    } 

    if (condition) { 
     if (fabs(i) > max_truncation_) { 
      i = 0; 
     } 
    } 

    if (fabs(i) > max_truncation_) { 
     i = 0; 
    } 
}; 


template<bool Condition> 
void Test<Condition>::CalculateTestingMemberVariable(double& i) { 
    i++; 
    if (condition_) { 
     if (fabs(i) > max_truncation_) { 
      i = 0; 
     } 
    } 

    if (condition_) { 
     if (fabs(i) > max_truncation_) { 
      i = 0; 
     } 
    } 
    if (fabs(i) > max_truncation_) { 
     i = 0; 
    } 
}; 

#endif // TEST_H_ 

和主要功能,一次在環(-O3)

#include <ctime> 
#include <chrono> 

#include "test.h" 

using namespace std; 

int main(int argc, char const *argv[]) { 

    Test<false>* object = new Test<false>(); 
    int iteration = 90000000; 

    std::chrono::time_point<std::chrono::system_clock> start, end; 
    start = std::chrono::system_clock::now(); 

    int i = 0; 
    double j = 0; 
    for(; i<iteration;i++) 
    { 
     object->CalculateTestingTemplate(j); 
    } 
    end = std::chrono::system_clock::now(); 
    std::chrono::duration<double> elapsed_seconds = end - start; 
    std::cout << "elapsed time: " << elapsed_seconds.count() << " " << j << "s\n"; 

    start = std::chrono::system_clock::now(); 

    i = 0; 
    j = 0; 
    for(; i<iteration;i++) 
    { 
     object->CalculateTestingStatic(j); 
    } 
    end = std::chrono::system_clock::now(); 
    elapsed_seconds = end - start; 
    std::cout << "elapsed time: " << elapsed_seconds.count() << " " << j << "s\n"; 


    start = std::chrono::system_clock::now(); 

    i = 0; 
    j = 0; 
    for(; i<iteration;i++) 
    { 
     object->CalculateTestingMemberVariable(j); 
    } 

    end = std::chrono::system_clock::now(); 
    elapsed_seconds = end - start; 
    std::cout << "elapsed time: " << elapsed_seconds.count() << " " << j << "s\n"; 


    return 0; 
} 
+1

您在定時循環結束時對'end'的賦值需要在您的'cout'語句之前_before_。否則,你會從輸出中獲得太多'噪音'。 – 1201ProgramAlarm

+0

我相信你對分析結果沒有任何意義。無論如何,-O3可能只是消除了大部分代碼。你應該看看最終的組裝代碼。 – Elazar

+0

@elazar,我完全刪除了cout,並更新了帖子,但結果相同(我也跑了很多次(即使在循環中但結果非常一致)) –

回答

1

你模板測試可能比預期的要慢,因爲它先運行,因此遇到緩存未命中,而其他測試不會遇到緩存遺漏,因爲模板測試已將數據帶入緩存。