更新:我很糟糕。这不是双重放缓的原因。我有其他的错误。
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中对象数的素数。对于300,000及以上的名单,这种放缓是显而易见的。
我切换到这个系统,以便我可以将所有对象存储在绘图列表中,并且可以使用相同的对象列表快速切换在不同窗口之间绘制的内容。这样可以大大加快切换时间,但减慢了每个绘图调用的速度。现在切换回来不是一个选项,我们知道它会减慢每个绘制调用的速度,但不是这么多。减速肯定在我向你展示的代码中,因为当我切换回绘制所有内容(删除查找)时,它会缩短一半的时间。
我提高性能的唯一想法是在列表中记录LastDrawn对象指针,并告知函数是否需要更改(调用lookup())或者它是否可以简单地重复使用最后绘制的(GetNext() )。从90%的时间来看,呼叫之间没有任何变化。
有没有人有比这更快的解决方案?我正在梦想一个棘手的位掩码解决方案,以某种方式产生我想要的对象指针,我不知道。在这一点上任何事情都会有所帮助。
答案 0 :(得分:1)
如果您将对象的指针而不是其ID存储到ListNow
中,您的问题似乎就会解决。