2013-08-20 87 views
4

這是我處理的代碼:這個程序需要很長時間才能關閉'返回'在main()的

#include <iostream> 
#include <map> 

using namespace std; 

static unsigned long collatzLength(unsigned long n) { 
    static std::map<unsigned long,int> collatzMap; 
    int mapResult = collatzMap[n]; 
    if (mapResult != 0) return mapResult; 

    if (n == 1) { 
     return 1; 
    } else { 
     collatzMap[n] = 1 + collatzLength(n%2==0?n/2:3*n+1); 
     return collatzMap[n]; 
    } 
} 

int main() { 
    int maxIndex = 1; 
    unsigned int max = 1; 
    for (int i=1; i<1000000; i++) { 
     //cout<<i<<endl; 
     unsigned long count = collatzLength(i); 
     if (count > max) { 
      maxIndex = i; 
      max = count; 
     } 
    } 
    cout<<maxIndex<<endl; 
    getchar(); 
    cout<<"Returning..."<<endl; 
    return maxIndex; 
} 

當我編譯和運行這個程序(使用Visual Studio 2012和Release構建設置),它需要像10秒(我的計算機上)關閉程序後打印「正在返回...」

這是爲什麼?

注意:我知道這個程序寫的不好,我可能不應該在collat​​zLength上使用'static',也不應該爲該函數使用緩存,但是我對如何使這個代碼更好,我只關心它爲什麼需要這麼多才能結束。

+4

首先運行需要多長時間?另外,每隔一段時間打印出一次'collat​​zMap'的大小可能會很有趣。很可能是破壞者仔細地釋放每一個需要這麼長時間的節點。 –

+1

collat​​zMap的最終尺寸約爲2,162,685。該漏洞程序需要約50secs在我的機器上運行 –

+1

嘗試運行釋放目標。如果調試速度很慢,那麼Visual Studio實現的額外安全性在發行版中實際上不是必需的。 (基本上用不同的方式來說SEbastian Redl說的) –

回答

4

轉到您的啓動項目「調試」部分的項目設置。輸入_NO_DEBUG_HEAP=1Environment部分。即使在發佈模式下也需要這樣做。

2

需要很長時間關閉,因爲collatzMapstatic,因此只會被釋放程序退出時,它包含了大量的數據,所以它會需要很長時間來獲得釋放(大小剛剛超過200萬,並且,由於map的工作原理,對於其中的每個至少有一個需要釋放的指針)。

也就是說,在Dev-C++上,退出時間不到一秒鐘。我猜Visual Studio沒有做好。

+0

但是十秒鐘? –

+0

它似乎有點長,但我看不到另一種解釋。 – Dukeling

+0

Visual Studio可能處於調試模式。 –

2

銷燬一個std::map在Visual Studio上非常慢,特別是對於Debug版本。相反,使用unordered_map應該已經消失。

VS的map實現構建了一個用於存儲數據的紅黑樹,這意味着您將不得不分配大量樹節點來存儲所有數據。銷燬期間的限制因素是遍歷樹並取消分配所有節點所需的時間。使用unordered_map時,遍歷通常要容易得多,因爲分配的桶通常較大,而不像紅黑樹節點那樣分散(儘管里程可能會有所不同)。

+1

你能詳細說明原因嗎? – Codecat

+0

我看到沒有區別使用unordered_map(該程序運行得更快,但仍需要很長時間才能關閉)另外我正在使用發佈版本 –

+0

這也許是真的,但更改底層數據結構應該不是一個真正可行的選擇。 'unordered_map'的行爲與地圖類似,但你必須實現散列函數,並且它可能不是在Trollkemada實現中使用的理想數據結構。 –

-1

在調試模式下運行VS時,有很多錯誤檢查標誌設置(例如邊界檢查,內存監視等)。由於您在靜態地圖中遞歸創建大量數據,因此它正在掃描內存在發佈之前確保沒有任何內容被損壞。當您切換到發佈版本時,應該幾乎是即時的。

經過進一步檢查,您基本上在內存的靜態部分分配了近100萬對(unsigned long,int)。這實際上意味着在應用程序可以完成關閉之前必須釋放〜8MB的數據(並且因爲map不需要連續,所以它必須遍歷所有100萬對以刪除每個數據)。其他實現可以通過預留大塊空間來優化存儲器使用(如果它預留了足夠的空間,例如100對,則會使解除分配過程減少2個數量級)。所有這些說,問爲什麼糟糕的代碼行爲不好就像問你爲什麼當你跳進游泳池時弄溼了。

+0

正如我已經在原始問題和一些評論中都說過的,我正在使用Release build。 –

+0

我錯過了那部分糟糕的代碼。現在我會調整我已經完成並調試它... –

0

我剛剛在我的機器上用VS 2012發佈版本試過。在「返回」後關閉程序的時間不超過2秒鐘。

相關問題