我花了最后一周将一个递归的Branch& Cut算法从Matlab移植到C ++,并希望看到解决方案时间显着减少,但是听起来令人难以置信,情况正好相反。 现在我不是C ++的专家,所以我下载了昏昏欲睡的探查器并试图找到潜在的瓶颈。我想问一下,我是否从中得出了正确的结论,或者我是否正在朝着一个完全错误的方向寻找。
我让代码运行137秒,这就是分析器显示的内容(下面的许多其他条目,但它们并不重要):
因此,如果我做对了,花了98秒创建新对象,花了34秒来释放内存(即删除对象)。
我会查看我的代码并查看我可以做得更好的地方,但我也想询问您是否对产生此类行为的常见错误或不良习惯有任何暗示。我想到的一件事是我在代码中使用了很多临时的std :: vector来计算东西,所以这可能很慢。
为了防止你失明,我不会在看了一会儿之前发布我的代码,但如果我不能自己解决这个问题,我会回来的。
答案 0 :(得分:5)
是的,如果误用,std::vector
可能会很昂贵。最大的性能影响可以是重新分配 - 因为大小需要动态调整,并且你有元素必须在连续内存中的约束,每当你添加超出已经分配的元素时,重新分配就会发生。
这就是为什么你要事先声明尺寸。如果您知道必须保留n
个元素,请将其声明为
std::vector<MyClass> x(n);
或
std::vector<MyClass> x;
x.reserve(n);
而不仅仅是
std::vector<MyClass> x;
后跟n
push_backs。
如果在此之后它仍然很慢,您可以为std::vector
提供自定义分配器。我希望你没有达到这一点。
答案 1 :(得分:1)
在Matlab中,一切都是对象的引用。因此,当你传递它们时,你就相当于复制一个指针(大小大小取决于几个因素),而不是复制整个矩阵,这可能是一个更大的矩阵。
没有看到任何代码,我不能肯定地说,但我怀疑你是在复制大量的对象,而不是复制对它们的引用。我建议您查看智能指针,例如std::shared_ptr
。
您没有说清楚,但您应该使用优化进行编译。 (g++ -O3
。)可以优化一些昂贵的副本和其他操作,但不是全部。
此外,如果您不熟悉C ++,则不应使用new
。这是专家,只有在与同事和一杯浓咖啡讨论后才能使用。 (当然,某些容器(例如new
)可能会代表您使用std::vector
。)
答案 2 :(得分:0)
正如Luchian Grigore所说,std :: vector很贵。但不仅如此,代码中不断创建对象,移动数据,重新分配内存甚至删除它的任何部分都可能非常耗时。如果亚历克斯张伯伦所说的是真的,那就有一个很大的瓶颈。如果没有,我会记住你(或者告诉你,如果你不知道),你做的几乎所有事情都会让你的软件在内存消耗方面更便宜,而且会在性能上付出代价。相反的情况也是如此,更多的内存消耗意味着cpu的计算量更少,因为你创建了之前计算过的所有内容的缓存。这是基本的,但有时我们会忘记它。
答案 3 :(得分:-1)
避免打电话给新&amp;删除准时关键代码。这很慢。或者使用快速内存管理器(例如SmartHeap)。