C ++性能:列表和迭代器

时间:2011-12-12 19:45:43

标签: performance visual-c++ g++

我有一些继承的内部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 ++经验)跳出原因?

2 个答案:

答案 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;

在该循环中,您可以看到每个操作都在您的个人资料中。