c++ 算法:搜索"列表"的子集,无序

c++ Algorithm: searching for a subset of a 'list', non-ordered

本文关键字:子集 无序 列表 搜索 c++ 算法      更新时间:2023-10-16

更新:我的坏消息。这并不是双减速的原因。我还有其他虫子。

C++MFC。Visual Studio 12。

我正试图在绘制循环中优化性能。我有一个我所有对象的列表(ListAll),假设它有300个对象,所有对象都有唯一的ID。我有第二个需要渲染的ID列表(ListNow),大小为100。ListNow中的所有值都有关联的对象存储在ListAll中。

当前,ListAll是一个CMap<UINT、UINT、Object*、Object*>和ListNow是一个CArray<UINT,UINT>。

// this is the slower, current method
for (int i = 0; i < ListNow.GetSize(); i++)
{
    UINT id = ListNow.GetAt(i);
    if (ListAll->Lookup(id, object))
    {
        object->draw();
    }
}

在过去,我只有ListAll(CMap),我对其中的每个对象都调用draw()。它只有我想要绘制的100个,每次切换绘制的内容时我都会"重建"它。

// this is the faster, old method
POSITION pos = ListAll->GetStartPosition();
while (pos)
{
    ListAll->GetNextAssoc(pos, id, object);
    object->Draw();
}

从技术上讲,这两种算法都以O(n)速度运行。。。但简单地将CMap::Lookup函数添加到循环中,所花费的时间就增加了一倍。我已经正确地将我的CMap大小设置为一个素数,该素数大于CMap中对象的数量。这种放缓在30万及以上的名单上是显而易见的。

我切换到这个系统,这样我就可以将所有对象存储在绘制列表中,并可以使用相同的对象列表在不同窗口之间快速切换。这大大加快了切换时的时间,但减缓了每个单独的平局呼叫。现在换回来不是一种选择,我们知道这会让每次抽签都慢一点,但不会慢那么多。减速肯定在我向您展示的代码中,因为当我切换回绘制所有内容(删除查找)时,它将时间减半。

我提高性能的唯一想法是将LastDrawn对象指针记录在列表中,并通知函数是否需要更改(调用lookup())或是否可以简单地重复使用上次绘制的指针(GetNext())。自从90%的时间以来,两次通话之间没有任何变化。

有没有比这更快的解决方案?我梦想着一个棘手的位掩码解决方案,它以某种方式产生我想要的对象指针,我不知道。在这一点上,任何事情都会有所帮助。

如果将对象的指针而不是它们的ID存储到ListNow中,问题似乎就会得到解决。