2015-11-30 51 views
0

就像一個實驗,我一直在運行下面的代碼塊。我在哪裏估計for循環中不同迭代次數所花費的時間。C++:在循環迭代中花費的時間

std::vector<double> numIt= {1e2, 1e4, 1e6, 1e8, 1e9, 1e10,1e11}; 
for(int i=0; i< (int) numIt.size() ; i++) 
{ 
    int tmp=0; 
    std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now(); 
    for (int j=0; j< numIt[i]; j++) 
    { 
     tmp=i-j; 
    } 

    std::chrono::high_resolution_clock::time_point t2 = std::chrono::high_resolution_clock::now(); 
    auto durationFPextraction = std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count(); 
    std::cout <<i<< "\t"<< tmp<<"\t"<<numIt[i] << "\t" << durationFPextraction <<std::endl; 
} 

它打印出以下內容,已經運行了幾個小時,現在通過1e+10長度for循環迭代。如果所花費的時間是線性的,它不應該花費大約14000毫秒(14秒)?

0 -99 100 0 1 -9998 10000 0 2 -999997 1e+06 2 3 -99999996 1e+08 144 4 -999999995 1e+09 1394

+9

什麼平臺?你確定'1e11'是否在你的整數範圍內?爲什麼比較一個整數到一個double? –

+2

將內循環更改爲'long int'並開始工作。這是一個明顯的整數溢出的情況。我的錯。謝謝。 – Yakku

回答

2

的幾個問題。

  1. 不要使用C風格的演員。
  2. 請勿使用int迭代vector,類型size_t是正確的使用方法。
  3. 您正在測量的東西是低音測量誤差閾值,因此數字將始終不可靠。
  4. 爲了正確測量,請使用如下所示:https://github.com/google/benchmark它將確保運行足夠的迭代以獲得統計信心。
1

正如David施瓦茨評論,句子

對(INT J = 0;Ĵ< numIt [I]; J ++)

因爲很可能不會適當是一個32位的值,不能代表你的numIt向量中的1e10和1e11值。將代碼更改爲使用long long(64位值)時,它將繼續循環。

#include <vector> 
#include <chrono> 
#include <iostream> 

int main (int argc, char *argv[]) 
{ 
    std::vector<double> numIt= {1e2, 1e4, 1e6, 1e8, 1e9, 1e10, 1e11}; 
    for(size_t i=0; i< numIt.size() ; i++) 
    { 
     int tmp=0; 
     std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now(); 
     for (long long j=0; j< numIt[i]; j++) 
     { 
      tmp=i-j; 
     } 
     std::chrono::high_resolution_clock::time_point t2 = std::chrono::high_resolution_clock::now(); 
     auto durationFPextraction = std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count(); 
     std::cout <<i<< "\t"<< tmp<<"\t"<<numIt[i] << "\t" << durationFPextraction <<std::endl; 
    } 
} 
1

int最有可能是32位。

如果是這種情況,那麼一旦你的int達到值2^31-1,將它增加1會產生未定義的行爲。實際上,未定義行爲的結果通常是將int設置爲最小可能值 - (2^31)。經過2^32次迭代後,你又回到了2^31 - 1,那麼j就會永遠變成 - (2^31)等等,並且永遠是真的。

您的代碼永遠不會結束運行。