std::矢量推进速度
std::vector pushing speed?
我正在使用vector来管理我的大型结构数据。但突然间,当我发现vector
源代码时,我非常惊讶地看到下面的一些代码:
inline void push_back(const _Ty& _X)
{insert(end(), _X); }
//...
void insert(iterator _P, size_type _M, const _Ty& _X)
{
//////////////////////////////////////////////////////////////
iterator _S = allocator.allocate(_N, (void *)0);
iterator _Q = _Ucopy(_First, _P, _S);
_Ufill(_Q, _M, _X);
_Ucopy(_P, _Last, _Q + _M);
_Destroy(_First, _Last);
allocator.deallocate(_First, _End - _First);
//////////////////////////////////////////////////////////////
}
这是"销毁"然后重新分配其整个矢量数据的片段代码。这太烦人了,因为我的结构很大,一个向量必须管理数百个元素,而我只使用vector::operator []
和vector::push_back()
,尤其是pushing back
占用了我大部分的程序时间(这很耗时)。在我的情况下,有没有比std::vector
更好的容器可以执行得更快,而我尝试了谷歌,但没有运气?
每次向量超过其当前容量时,分配复制删除(或C++11中的分配移动删除)只发生一次余复杂性是常数。
您可以使用向量的reserve()
成员函数预先分配向量的容量。
在添加元素之前保留所需的所有空间会解决您的问题吗?
如果知道最终的数据大小,可以使用reserve
预先分配向量所需的内存。这将删除所有重新分配和复制。
如果你不知道确切的大小,根据你对传入数据的了解做出有根据的猜测。
只有当矢量大小超过其容量时,才会发生重新定位。如果你提前(甚至大致)知道你的向量将包含多少个项目,你可以使用它的储备成员来预先分配足够的容量。您还可以以可控的方式触发重新分配,即使在填充向量时也是如此,以减少调用向量的次数,从而获得更好的性能。
现在,如果您想要有保证的恒定时间插入,那么有一些容器可以用于此操作,但需要权衡(例如,std::list
将分配大量的小内存块,这些内存块最终可能不会比您当前矢量使用的速度快,因为new
非常慢,内存使用也会更重要,并且您会失去随机访问,但每次插入所需的时间肯定与其他插入所需时间大致相同)。
向量是一个动态扩展的容器,但它的内容必须在一个连续的内存块中(我记得,这在C++11之前是未指定的,但每个人都这样做了)。因此,如果您的向量已经包含8个元素,并且向量的当前容量为8个元素。那么,当您推送第9个元素时,容器必须为更大的容量分配新的空间,复制容器中已经存在的8个元素、将第9个元素复制到新的空间中,然后销毁旧的。如果你使用的是C++11,并且你的元素支持移动构造,那么8个副本可以变成8个移动。或者,如果你想承担管理指针的开销,你可以存储指向元素的指针,而不是元素(复制指针很便宜,但现在你需要处理寿命问题)。
至于哪个容器比向量快,这是一个很大的开放式问题。它取决于各种访问/操作模式。std::list被提到作为候选。O(1)添加到列表的末尾,但可能比向量使用的摊销O(1。您失去了对容器的随机访问权限。
是的,push_back()
在大多数时候都是常数,但当size()
到达capacity()
时,需要重新分配整个向量。
如果您想要恒定时间插入,则必须尝试std::list
或std::deque
。特别是std::deque
在容器的末尾提供了正确的插入性能,同时在其接口中接近向量。
从cpp引用中提取:
因此,它们提供了与矢量类似的功能,但在序列的开始处,而不仅仅是在序列的结束处,它们还具有元素的有效插入和删除。但是,与向量不同,deques不能保证将其所有元素存储在连续的存储位置,因此不允许通过偏移指向元素的指针来直接访问。
- 为什么std::condition_variable notify_all的工作速度比notify_one快(对于随机请
- C# HashSet VS C++ std::unordered_set 使用自定义类键。C++慢...不可能。如何实现 C# 的速度?
- 为什么 std::set 遍历所有元素的速度较慢?
- 为什么用std :: sort()对上升阵列(1〜100,000)排序比仅使用100,000次使用的速度要快
- std::结构复杂,使编译速度变慢
- 线程锁定互斥锁的速度比 std::conditional_variable::wait() 快
- 添加 g++ 的 -std= 标志时,C++打印到终端的速度要慢得多?
- 使用std :: async时,为什么通过const ref速度较慢
- 如何提高 ifstream 和 ofstream 的读写速度 std::vector<uint8_t>
- 速度/效率:我应该并行化这个std::map插入吗
- std::tan()在更新glibc后速度非常慢
- 为什么std::async与简单的分离线程相比速度较慢
- 分配std::vector数组会减慢后续计算的速度
- 访问std::vector元素的速度会随着向量大小而减慢
- 将数据保存在std :: vector或.txt文件中的速度更快
- 为什么将 std::endl 与 ostringstream 一起使用会影响输出速度
- Java使用数组的速度是C++中std::vector的8倍.我做错了什么
- std::map::erase()-重载速度更快
- std::线程的创建使主程序的速度减慢了50%
- gcc std::unordered_map 实施速度慢吗?如果是这样 - 为什么