2012-12-04 123 views
2

我有一個std :: map性能問題。在我的C++項目中,我有一個GUIObject的列表,其中還包括Window s。我在for循環繪製的一切,就像這樣:std :: map performance C++

unsigned int guiObjectListSize = m_guiObjectList.size(); 
for(unsigned int i = 0; i < guiObjectListSize; i++) 
{ 
    GUIObject* obj = m_guiObjectList[i]; 
    if(obj->getParentId() < 0) 
    obj->draw();         
} 

在這種情況下,當我運行一個項目,它工作的順利進行。我有4個窗口和其他一些部件,如按鈕等

但我想借此分別繪製窗口的照顧,所以修改後,我的代碼看起來是這樣的:

// Draw all objects except windows 
unsigned int guiObjectListSize = m_guiObjectList.size(); 
for(unsigned int i = 0; i < guiObjectListSize; i++) 
{ 
    GUIObject* obj = m_guiObjectList[i]; 
    if((obj->getParentId() < 0) && (dynamic_cast<Window*>(obj) == nullptr)) 
     obj->draw();  // GUIManager should only draw objects which don't have parents specified 
          // And those that aren't instances of Window class 
          // Rest objects will be drawn by their parents 
          // But only if that parent is able to draw children (i.e. Window or Layout) 
} 

// Now draw windows 
for(int i = 1; i <= m_windowList.size(); i++) 
{ 
    m_windowList[i]->draw(); // m_windowList is a map! 
} 

所以我創建了一個std::map<int, Window*> ,因爲我需要在地圖中將Window的z索引設置爲key。但問題是,當我運行這個代碼時,它真的很慢。即使我只有4個窗口(地圖大小爲4),我可以看到fps率非常低。我不能說一個確切的數字,因爲我還沒有實施這樣的計數器。

誰能告訴我爲什麼這種方法如此之慢?

+1

你確定它不是dynamic_cast這是慢嗎? – Agentlien

+0

避免dynamic_cast,特別是在循環中 – codablank1

+0

@Agentlien是的,我試圖刪除if語句中的dynamic_cast條件並離開地圖內容繪圖(因此繪製了多於2個的窗口,但是這個數字不是很多),但仍然非常緩慢。 –

回答

4

這是虛擬功能的用途。您不僅可以消除緩慢的dynamic_cast,而且可以獲得更靈活的類型檢查。

// Draw all objects except windows 
unsigned int guiObjectListSize = m_guiObjectList.size(); 
for(unsigned int i = 0; i < guiObjectListSize; i++) 
{ 
    GUIObject* obj = m_guiObjectList[i]; 
    if(obj->getParentId() < 0) 
     obj->drawFirstChance(); 
} 

// Now draw windows 
for(int i = 1; i <= m_windowList.size(); i++) 
{ 
    m_windowList[i]->drawSecondChance(); 
} 

其中drawFirstChance對Windows和其他浮動對象沒有任何作用。

下一個優化的機會是使窗口列表爲vector並且只有當它改變時(假設窗口創建/銷燬/重新排序的次數比它們繪製的次數少)才執行z順序排序。

2

該代碼的問題似乎與使用std :: map不同。相反,瓶頸是使用dynamic_cast,這是一個非常昂貴的操作,因爲它需要漫遊給定類的繼承樹。

這棵樹對於你的GUI組件來說很可能是相當大的,這肯定會解釋爲什麼每次迭代時都這樣做會減慢整個方法的速度。

+0

謝謝你的答覆Agentlien,但正如我回復你的評論 - 我試圖刪除if語句中的這dynamic_cast條件和離開地圖內容繪圖(所以有2倍的窗口繪製,但這個數字,8,不是數量非常大),但仍然非常緩慢。 –

+0

我剛剛發佈我的答案後就看到了。你有沒有試過簡單地評論draw()代碼? – Agentlien

+0

如果我將地圖內容的draw()註釋掉,它可以很好地工作。 –