C ++“删除”很慢。我应该先在哪里看?

时间:2011-01-20 21:19:21

标签: c++ memory-management

我有一个C ++应用程序,其中“删除”功能运行缓慢。可能导致这种情况的原因以及我应该从哪里开始寻找解决方案?

背景

此C ++代码位于AutoCAD内部运行的ARX文件中,该文件基本上只是一个DLL。

删除速度慢的特定计算机正在运行AutoCAD 2011,Windows 7,64位。必须使用Visual Studio 2008 Service Pack 1编译ARX for AutoCAD 2011。

有问题的电脑是客户的电脑。它没有安装任何版本的Visual Studio。

在我的开发计算机上,代码在AutoCAD 2011中没有任何问题。

为了测试,我有一些删除链表的代码。在有问题的计算机上,删除列表需要0.7秒。在没有问题的计算机和配置上,相同的代码需要0.02秒。具体时间并不重要 - 两个数字之间的差异很大。

我确保在两台计算机上运行相同版本的代码,因此它不是发布与调试构建问题。

5 个答案:

答案 0 :(得分:5)

大致按照我检查的顺序:

  • 其他插件:可能由其他ARX文件引起的行为?他们可以在糟糕的系统上被禁用吗?
  • PerfMon:检查删除期间软/硬页面错误或缓存未命中是否达到峰值(我希望您可以在客户计算机上进行设置)。
  • HeapQueryInformation:在好/坏环境中的相同值?
  • 堆锁:其他一些线程可能在后台高度活跃,紧紧抓住堆的锁吗?您可以通过将循环包装在HeapLock / HeapUnlock中来测试(当然还有锁内的时间)。
  • 挂钩:可以挂钩相应的代码吗? (例如,第三方应用程序挂钩到C ++ / Win32堆函数以执行它想做的任何事情)
  • 抓住吸管:相应的new花费多长时间?个人delete时间如何分配?

答案 1 :(得分:1)

可能是由于工作/故障系统之间的缓存效率不同。故障系统上可能存在更多内存碎片,导致大型删除会破坏缓存。在静态系统上,数据最终可能会更顺序,并在大删除期间获得更多缓存命中。

试试英特尔性能计数器监视器?

答案 2 :(得分:1)

如果可以接受并且可能,请尝试在客户的计算机上使用分析器。

您可以尝试使用AMD CodeAnalyst或英特尔资料管理器(尽管该资料管理器不是免费的)。

如果无法做到这一点,则将分析代码添加到发布版本中并从客户收集结果。即使是简单的分析代码也可以帮助您找到真正的瓶颈。

它看起来不像删除本身就是问题,但问题可能是代码的其他部分。

E.g。 - head->resval.rstring的类型是什么?

答案 3 :(得分:0)

我们一直都遇到这种情况。您的代码没有任何问题,即使在发布模式下,删除数千个项目也可能需要几秒钟(而且我已经看到它也达到了几分钟)。

答案是不删除。让自己成为一个真正的内存分配器,而不是单独分配每个对象创建一个内存池(或自定义堆或任何你想要调用它)。 Nedmalloc是我们使用和推荐的内容,您可以创建“nedpool”。基本上,池是一个内存块,您的对象将从中分配。您仍然为每个对象分配内存,但它从池中获取而不是直接从操作系统中获取。

当删除时间到来时,您只需删除整个池而不是逐个删除对象。对将要同时过期的每批对象使用不同的池。您不需要预先为整个池分配内存,但是您只能一次删除整个池。

答案 4 :(得分:0)

如何生成retlist?另外,您是否有理由手动分配和删除resbufs而不是使用acutNewRb和acutRelRb?

此外,您可能已经检查了这些,但用户是否在AutoCAD 2009和2011中都加载了默认图纸?如果没有,图纸是否相同(ACAD版除外),它们是位于本地还是位于网络驱动器上?您还可以查看用户是否在两个实例中都运行相同的lisp / .Net / objectARX应用程序。此外,AutoCAD 2011是网络还是本地安装?

最后,您可能希望在问题中添加autocad和objectarx标记。