C++ 标准::映射性能c++;

C++ 标准::映射性能c++;,c++,stl,map,containers,C++,Stl,Map,Containers,我对std::map性能有问题。在我的C++项目中,我有一个清单: GuiObjult,它也包含代码>窗口< /代码> s。我在for循环中绘制所有内容,如下所示: unsigned int guiObjectListSize = m_guiObjectList.size(); for(unsigned int i = 0; i < guiObjectListSize; i++) { GUIObject* obj = m_guiObjectList[i]; if(obj-&

我对std::map性能有问题。在我的C++项目中,我有一个清单:<代码> GuiObjult<代码>,它也包含代码>窗口< /代码> s。我在
for
循环中绘制所有内容,如下所示:

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();                                
}
// 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!
}
unsigned int guiObjectListSize=m_guiObjectList.size();
for(unsigned int i=0;igetParentId()<0)
obj->draw();
}
在这种情况下,当我运行一个项目时,它工作得很顺利。我有4个窗口和一些其他组件,如按钮等

但我希望单独绘制窗口,因此在修改后,我的代码如下所示:

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();                                
}
// 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!
}
//绘制除窗口以外的所有对象
unsigned int guiObjectListSize=m_guiObjectList.size();
for(unsigned int i=0;igetParentId()<0)和&(dynamic_cast(obj)=nullptr))
obj->draw();//GUI管理器应该只绘制没有指定父对象的对象
//以及那些不是Window类实例的
//静止对象将由其父对象绘制
//但前提是该父级能够绘制子级(即窗口或布局)
}
//现在画窗户
对于(int i=1;i draw();//m_windowList是一个映射!
}
所以我创建了一个
std::map
,因为我需要将
Window
s的z索引设置为映射中的
key
s。但问题是,当我运行此代码时,速度非常慢。即使我只有4个窗口(映射大小为4),我可以看到fps速率非常低。我不能说确切的数字,因为我还没有实现这样的计数器


有人能告诉我为什么这种方法这么慢吗?

这段代码的问题似乎不在于使用std::map。相反,瓶颈在于使用
动态转换,这是一个非常昂贵的操作,因为它需要遍历给定类的继承树


对于GUI组件来说,此树很可能相当大,这肯定可以解释为什么每次迭代中这样做会降低整个方法的速度。

这就是虚拟函数的用途。不仅可以消除缓慢的
动态转换,还可以获得更灵活的类型检查

// 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();
}
//绘制除窗口以外的所有对象
unsigned int guiObjectListSize=m_guiObjectList.size();
for(unsigned int i=0;igetParentId()<0)
obj->drawFirstChance();
}
//现在画窗户
for(int i=1;i drawSecondChance();
}
其中
drawFirstChance
对windows和其他浮动对象没有任何作用


下一个优化机会是使窗口列表成为一个
向量
,并仅在其更改时执行z顺序排序(假设创建/销毁/重新排序窗口的频率比绘制窗口的频率低得多).

你确定不是动态施法慢吗?避免动态施法,尤其是在loop@Agentlien是的,我尝试在if语句中删除这个动态_cast条件,并保留映射内容绘图(因此绘制的窗口数量增加了2倍,但这个数字8并不是很大),但速度仍然很慢。使用探查器,看看实际瓶颈在哪里。
m_windowList
为什么是一个映射?你是用一个整数而不是更复杂的东西建立索引,而且索引很密集(显然是从1到
size()-1
),这表明是一个向量或deque。有了向量,你的
m_windowList[i]
是一个O(1)操作。对于映射,它是一个O(log(n))操作。感谢您的回答Agentlien,但正如我对您的评论所作的回答-我尝试在if语句中删除此动态强制转换条件,并留下映射内容绘图(因此绘制的窗口多了2倍,但这个数字8不是很大),但速度仍然非常慢。我在发布答案后看到了这一点。您是否尝试过简单地注释draw()代码?如果我注释地图内容的draw(),效果会非常好。这似乎表明实际问题在于draw调用,而不是存储它们的地图,不是吗?