2012-12-04 120 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()注释掉,它可以很好地工作。 –