3

上周我将递归 Branch&Cut 算法从 Matlab 移植到 C++,并希望看到求解时间显着减少,但尽管听起来令人难以置信,但情况恰恰相反。现在我并不是真正的 C++ 专家,所以我下载了 sleepy profiler 并试图找到潜在的瓶颈。我想问一下我是否从中得出正确的结论,或者我是否正在寻找一个完全错误的方向。

我让代码运行了 137 秒,这就是分析器显示的内容(下面还有许多其他条目,但它们无关紧要):

在此处输入图像描述

所以如果我做对了,98 秒用于创建新对象,34 秒用于释放内存(即删除对象)。

我会检查我的代码,看看哪里可以做得更好,但我也想问你是否有任何关于导致这种行为的常见错误或坏习惯的提示。我想到的一件事是我在代码中使用了很多临时的 std::vectors 来计算东西,所以这可能会很慢。

为了防止你失明,在我仔细查看之前我不会发布我的代码,但如果我不能自己解决这个问题,我会回来的。

4

4 回答 4

5

是的,std::vector如果误用,s 可能会很昂贵。最大的性能损失可能是重新分配 - 因为大小需要动态调整,并且元素必须在连续内存中,所以每当您添加超出已分配内容的新元素时,就会发生重新分配。

这就是为什么您应该事先声明尺寸。如果您知道必须保存n元素,请将其声明为

 std::vector<MyClass> x(n);

或者

 std::vector<MyClass> x;
 x.reserve(n);

而不仅仅是

 std::vector<MyClass> x;

其次是npush_backs。

如果在此之后它仍然很慢,您可以提供std::vector自定义分配器。我希望你不要到那个地步。

于 2013-01-25T14:05:49.083 回答
1

在 Matlab 中,一切都是对对象的引用。因此,当您传递它们时,您相当于复制一个指针(大小约为 int,具体取决于几个因素),而不是复制整个矩阵,这可能更大。

没有看到任何代码,我不能肯定地说,但我怀疑你正在复制大量对象而不是复制对它们的引用。我建议您研究智能指针,例如std::shared_ptr.

你没有说清楚,但你应该进行优化编译。( g++ -O3.) 一些昂贵的副本和其他操作可以优化出来,但不是全部。

此外,如果您是 C++ 新手,则不应使用new. 它是为专家准备的,只有在与同事讨论并喝了一杯浓咖啡后才能使用。(当然,new可能会被某些容器代表您使用,例如std::vector。)

于 2013-01-25T14:05:46.047 回答
0

正如 Luchian Grigore 所说, std::vector 很昂贵。但不仅如此,代码中不断创建对象、移动数据、重新分配内存甚至删除它的任何部分都可能非常耗时。如果亚历克斯·张伯伦所说的是真的,那就有很大的瓶颈。如果不是,我会记得你(或者告诉你,如果你不知道的话),几乎你所做的每一件事都会让你的软件在内存消耗方面更便宜,它会以性能为代价。反之亦然,更多的内存消耗意味着 cpu 的计算量更少,因为你对之前计算的所有内容进行了缓存。这是基本的,但有时我们会忘记它。

于 2013-01-25T14:33:20.807 回答
-1

避免在时间关键代码上调用 new & delete。它很慢。或者使用快速内存​​管理器(例如 SmartHeap)。

于 2013-01-25T14:05:55.993 回答