STL复制功能的效率

时间:2015-08-21 16:40:57

标签: c++ c++11 stl

我正在尝试从条目列表中构造一组唯一的单词,每个条目都有一个字符串向量。

所以我创建了一个名为Insert的函数,它会为每个条目调用,如下所示:

for( auto & e : _Entries )
    _Dictionary.Insert( begin( e.getNameWords( ) ), end( e.getNameWords( ) ) );

类_Dictionary内部有一个set(STL容器),我编写了Insert函数,如下所示:

template< typename InputIterator >
void Insert( InputIterator first, InputIterator last )
{
    for( auto it = first ; it != last ; ++it )
        _AllWords.insert( *it );
 }

就我而言,为_Entries中的所有条目调用Insert平均花费了570毫秒。

然后我认为我应该使用STL已经具有的功能与Insert中的for循环相同的功能,所以我将函数Insert更改为以下内容:

template< typename InputIterator >
void Insert( InputIterator first, InputIterator last )
{
    copy( first, last, inserter( _AllWords, begin( _AllWords ) ) );

}

我期待这个

  1. 更正确,
  2. 至少要快,如果不是更多
  3. (让STL尽可能为你做的事情的哲学指导)。但是,我惊讶地发现这种实施实际上需要更长时间;没有多少,但比之前的基于for循环的实现要多200毫秒。

    我知道这是一个基本上微不足道的速度差异,但我仍然感到惊讶。

    所以我的问题是:为什么我的实施更快?

    注意:我正在使用clang的版本3.5.2和libc ++标准库以及-O3标志在Ubuntu 14.04下进行编译。

1 个答案:

答案 0 :(得分:12)

问题在于:

copy( first, last, inserter( _AllWords, begin( _AllWords ) ) );

最终调用此版本的insert

iterator insert( iterator hint, const value_type& value );

begin()作为提示。也就是说,通常情况下,不是您想要插入每个值的位置。因此,您只是让容器做更多的工作,试图找出您的hint 尽可能糟糕的价值添加位置。

但请注意,insert

也有这种重载
template< class InputIt >
void insert( InputIt first, InputIt last );

你应该使用

template< typename InputIterator >
void Insert( InputIterator first, InputIterator last )
{
    _AllWords.insert(first, last);
}

并注意,_AllWords是保留的标识符。

<小时/> 虽然基于此note

  

重载(5-6)通常实现为一个循环,以end()作为提示调用overload(3);它们被优化用于附加排序的序列(例如另一个集合),其最小元素大于*this中的最后一个元素

这似乎是一个非常具体的目标来优化,你可能会或可能不会满足,所以可能你不应该使用这个重载,你的初始循环就好了。