我有一些继承的内部C ++代码,在Windows上使用VC ++编译时,比在Linux上使用g ++编译时(5分钟对2小时)运行速度快一个数量级。无论有没有“正常”优化标志,以及每个编译器和相应平台的几个不同版本,所有这些都在类似的硬件上。
使用g ++在Linux上构建调试/配置文件版本(-g -pg),我发现以下三个方面大部分时间都在消耗:
% cumulative self self total
time seconds seconds calls Ks/call Ks/call name
31.95 955.93 955.93 3831474321 0.00 0.00 std::_List_const_iterator<xxFile>::operator!=(std::_List_const_iterator<xxFile> const&) const
22.51 1629.64 673.71 3144944335 0.00 0.00 std::_List_const_iterator<xxFile>::operator++()
15.56 2095.29 465.65 686529986 0.00 0.00 std::iterator_traits<std::_List_const_iterator<dtFile> >::difference_type std::__distance<std::_List_const_iterator<xxFile> >(std::_List_const_iterator<xxFile>, std::_List_const_iterator<xxFile>, std::input_iterator_tag)
(xxFile类由int,浮点数,双精度数,bool数和字符串组成)
我天真的猜测是,VC ++正在补偿的编码很差或者GNU STL可能没有那么优化。我目前正在使用Boost库编译g ++ / Linux版本,从assign / std / list.hpp和boost :: assign命名空间开始。
我无法分享代码,但根据您的经验,做一些显而易见的事情(除了我有限的C ++经验)跳出原因?
答案 0 :(得分:2)
我会抛弃一些事情而不知道你的代码,除非它花费大量时间迭代列表。
您需要使用列表吗?
如果您花费大量时间进行迭代,那么您可能应该使用连续的数据结构(数组/向量)。除非您因某些其他原因需要列表行为(即,在其他地方进行大量插入,否则可能会占用您的运行时),因此使用数组会因内存局部性而提供更好的性能。即使迭代一个数组和列表都是O(n),实际上由于适当利用CPU的缓存,数组可以更快。当你浏览一个列表 - >接下来你不知道你可能会在哪里结束,如果你一直在页面错误,你将会有糟糕的表现。
你在进行大量搜索吗?也许很多线性搜索?
operator!=位于列表顶部的事实使它看起来像这样。谁在呼唤那个以及为什么?如果您正在进行大量搜索并且这会占据您的运行时,您可能还需要考虑不同的数据结构,如果您进行大量插入和查找,可能需要使用二进制搜索树或哈希表。
答案 1 :(得分:0)
因为顶级项目是距离,运算符++和运算符!=我相信您的问题是在列表中使用size()
操作。
这是C ++标准允许不同实现的那些领域之一。 MSVC实现将列表的大小存储为数字,因此返回值非常快。 GCC没有,所以要获得列表的大小,它必须基本上执行:
count = 0;
for(
list::iterator it = l.begin()
it != l.end();
++it
)
++count;
在该循环中,您可以看到每个操作都在您的个人资料中。