优化std :: deque中的搜索

时间:2018-11-06 12:34:22

标签: c++ optimization data-structures std deque

我正在做一个具有不同对象的程序,它们都是虚拟类的子对象。我这样做是为了寻找多态的优势,这些优势使我可以从管理器类中调用所有对象的特定方法,而无需检查其具体类型。

重点是有时需要获取某种类型的对象列表的不同类型的对象。

那一刻,我的经理类循环考虑了所有对象并检查了对象的类型。它会创建一个列表并返回如下:

std::list<std::shared_ptr<Object>> ObjectManager::GetObjectsOfType(std::string type)
{
    std::list<std::shared_ptr<Object>> objectsOfType;

    for (int i = 0; i < m_objects.size(); ++i)
    {
        if (m_objects[i]->GetType() == type)
        {
            objectsOfType.push_back(m_objects[i]);
        }
    }

    return objectsOfType;
}

m_objects 是双端队列。我知道迭代数据结构通常很昂贵,但我想知道是否有可能对其进行一些修饰,因为现在此函数需要花费程序中所有时间的三分之一。

我的问题是:为了降低程序中此操作的成本,是否没有考虑任何设计模式或功能?

2 个答案:

答案 0 :(得分:2)

在给出的代码中,只有一个优化可以在本地完成:

for (auto const& obj : m_objects)
{
    if (obj->GetType() == type)
    {
        objectsOfType.push_back(obj);
    }
}

基本原理是operator[]通常不是访问deque的最有效方法。话虽如此,我并不期望会有重大改善。您的引用位置非常差:您实际上正在查看两个取消引用(shared_ptrstring)。

一种逻辑方法是使m_objects成为按类型键入键的std::multimap

答案 1 :(得分:1)

您可以采取一些措施来加快速度:

  • 将类型存储在基类上,这将删除稍微昂贵的虚拟查找。
  • 如果类型是string等,请更改为
    简单类型,例如枚举或整数
  • vector的效率更高
    deque遍历
  • 如果停留在deque上,请使用迭代器或基于范围的for循环来避免随机查找(在deque中更昂贵)

基于范围的外观如下:

for (auto const& obj : m_objects)
{
    if (obj->GetType() == type)
    {
        objectsOfType.push_back(obj);
    }
}

更新:我也建议您不要使用std::list(除非出于某些原因,除非如此),因为在许多情况下它的运行效果并不佳-再次std::vector可助您一臂之力!