0

在观察了我的程序中的一些性能问题后,我决定运行一个分析会话。结果似乎表明,大约 87% 的样本与我的Update()功能有关。

在这个函数中,我将遍历一个等于 72 的列表A*sizeof(A)并在处理后删除它们。

void Update()
{
//...

    for(auto i = myList.begin(); i != myList.end(); i++)
    {
        A* pA = *i;
        //Process item before deleting it.
        delete pA;
    }

     myList.clear();

//...
}

其中 myList 是一个std::list<A*>. 平均而言,我每秒调用此函数 30 到 60 次,而列表平均包含 5 个项目。这意味着我A每秒要删除 150 到 300 个对象。

在大多数情况下,多次调用 delete 是否足以导致性能问题?有什么方法可以准确追踪问题发生在函数的哪个位置?删除通常被认为是一项昂贵的操作吗?

4

3 回答 3

1

很难说,因为你刷过可能是循环中完成的大部分工作并且没有暗示 A 是什么......

如果 A 是一个简单的数据集合,尤其是原语,那么删除几乎肯定不是罪魁祸首。您可以通过将更新函数分成两部分来测试理论 - update 和 uninit。更新完成所有处理, uninit 删除对象并清除列表。

如果只是更新很慢,那就是处理。如果只有 uninit 很慢,那就是删除。如果两者都很慢,那么内存碎片可能是罪魁祸首。

正如其他人在评论中指出的那样, std::vector 可能会给您带来性能提升。但要小心,因为它也可能在其他地方导致性能问题,具体取决于您构建数据结构的方式。

于 2012-12-13T21:00:16.457 回答
0

您可以从gperftools(Google 性能工具)查看tcmalloc 。gperftools 还包含一个分析器(两个库只需要链接,非常简单)。tcmalloc 为小对象保留一个内存池,并在可能的情况下重新使用该内存。分析器可用于 CPU 和堆分析。

于 2012-12-13T22:57:46.510 回答
0

很容易知道发生了什么。

帮自己一个忙,使用这个方法。分析到n级,非常有效。

简而言之,如果 87% 的时间都在Update,那么如果你只是用 Ctrl-C 或其他什么来停止它几次,那么每次你在行动中抓住它的概率是 87%。

您不仅会看到它在Update. 您将看到在哪里Update以及它在做什么。如果它正在处理delete,或者访问数据结构,你会看到。您还将在堆栈的更下方看到该操作需要时间的原因。

于 2012-12-13T23:08:47.620 回答