【问题标题】:Optimize search in std::deque优化 std::deque 中的搜索
【发布时间】:2019-04-09 20:29:06
【问题描述】:

我正在编写一个具有不同类型对象的程序,并且它们都是虚拟类的子级。我这样做是为了寻找多态性的优点,它允许我从管理器类调用所有对象的某个方法,而无需检查它是什么特定类型的对象。

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

在那一刻,我的管理器类循环考虑了所有对象并检查了对象的类型。它创建一个列表并像这样返回它:

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 是一个双端队列。我知道迭代一个数据结构通常很昂贵,但我想知道是否可以稍微改进一下,因为现在这个函数占用了程序中所有时间的三分之一。

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

【问题讨论】:

  • 放弃string 并使用int。放弃list 并使用vector
  • @PasserBy 我想到了向量点。但是在我的程序开始时不知道我将拥有多少个对象并且无法为它们保留空间是否值得?
  • 正式的回应是:这取决于您的用例。一个现实的反应是:我在开玩笑,总是对的。
  • 是的,当然。随着列表大小的增加,随机访问将变得越来越慢,非常慢,甚至一次读取一个与向量相比也会非常慢。 Vector 不会在每次推送元素时重新分配,它会在推送时自动保留一些空间,以避免过于频繁地重新分配。
  • @Asu:你为什么要假设随机访问?代码清楚地显示了线性访问。

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


【解决方案1】:

你可以做一些事情来加快速度:

  • 将类型存储在基类中,这将消除一些昂贵的虚拟查找。
  • 如果类型是string等,则改为a
    简单类型,例如 enum 或 int
  • vector 更高效
    遍历deque
  • 如果使用 deque,请使用迭代器或基于范围的 for 循环来避免随机查找(在 deque 中更昂贵)

基于范围的看起来像这样:

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

更新:另外我建议不要使用std::list(除非出于某种原因你必须这样做),因为它在许多情况下表现不佳 - 再次std::vector 可以救援!

【讨论】:

    【解决方案2】:

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

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

    理由是operator[] 通常不是访问deque 的最有效方式。话虽如此,我预计不会有重大改进。您的引用位置很差:您实际上是在查看两个取消引用(shared_ptrstring)。

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

    【讨论】:

      猜你喜欢
      • 2017-12-19
      • 2011-10-14
      • 1970-01-01
      • 2015-07-20
      • 1970-01-01
      • 1970-01-01
      • 2013-03-07
      • 1970-01-01
      • 2015-12-12
      相关资源
      最近更新 更多