简体   繁体   English

C ++中向量初始化的性能

[英]Performance of vector initialization in C++

Suppose you initialize a vector from another container: 假设您从另一个容器初始化向量:

main()
{
    list<int> L { 0, 1, 2 };
    vector<int> V ( L.begin(), L.end() );
    copy ( V.begin(), V.end(), ostream_iterator<int> ( cout, " " ) );
    cout << endl;
}

Does the vector size get set once, or is it dynamically resized during initialization? 向量大小是否设置一次,还是在初始化期间动态调整大小? (Not an issue in this example as the source has few elements, but could be an issue if the source has very many elements.) (由于源中元素很少,因此在此示例中不成问题,但是如果源中元素太多,则可能是一个问题。)

You are calling std::vector 's templated constructor with two iterators (and a hidden allocator parameter). 您正在使用两个迭代器(和隐藏的分配器参数)调用std::vector的模板化构造函数。 This is what the relevant Standard quote says: 这是相关标准语录的意思:

23.3.6.2 vector constructors, copy, and assignment [vector.cons] 23.3.6.2矢量构造函数,复制和分配[vector.cons]

template <class InputIterator> 
vector(InputIterator first, InputIterator last, const Allocator& = Allocator());

9 Effects: Constructs a vector equal to the range [first,last), using the specified allocator. 9效果:使用指定的分配器构造一个等于[first,last)范围的向量。

10 Complexity: Makes only N calls to the copy constructor of T (where N is the distance between first and last) and no reallocations if iterators first and last are of forward, bidirectional, or random access categories . 10复杂度:仅对T的副本构造函数进行N次调用(其中N是第一个和最后一个之间的距离), 并且如果第一个和最后一个迭代器属于前向,双向或随机访问类别,则不进行任何重新分配 It makes order N calls to the copy constructor of T and order log(N) reallocations if they are just input iterators. 如果它们只是输入迭代器,它将对T的副本构造函数进行N阶调用,并对其进行log(N)重分配。

Because you are initializing from a std::list (bidirectional iterators) there will be only one allocation. 因为您是从std::list (双向迭代器)初始化的,所以只会分配一个。

Reading from standard input, OTOH, is done using input iterators and then there could be multiple reallocations. 使用输入迭代器完成从标准输入OTOH的读取,然后可能会有多个重新分配。 Note though that the average number of times that an element is being moved around in memory is still O(1) (because of the exponential memory allocation strategy). 但是请注意,元素在内存中移动的平均次数仍为O(1) (由于采用指数内存分配策略)。

According to the standard at §23.3.6.2/10, there are no reallocations as long as the iterators are forward iterators, bidirectional iterators, or random access iterators. 根据§23.3.6.2/ 10中的标准,只要迭代器是前向迭代器,双向迭代器或随机访问迭代器,就没有重新分配。 There are O(log N) reallocations if the iterators are input iterators. 如果迭代器是输入迭代器,则存在O(log N)重新分配。

Note: std::list has bidirectional iterators. 注意: std::list具有双向迭代器。

How is this implemented, you ask? 您问这是如何实施的? Presumably, it makes one pass to calculate the distance between the two iterators (or calls std::distance or an internal version) and then makes another pass to actually initialize the vector. 大概,它通过了一次以计算两个迭代器之间的距离(或调用std::distance或内部版本),然后又进行了另一遍以实际初始化向量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM