std::vector::emplace()实现解析及自定义实现性能疑问
GCC std::vector::emplace() 源码执行逻辑解析
场景背景
自定义实现的vector类中,emplace()方法性能远低于std::vector::emplace(),查看GCC源码后无法理解其执行逻辑,以下是对这段源码的详细拆解。
GCC std::vector::emplace() 源码
template<typename _Tp, typename _Alloc> template<typename... _Args> typename vector<_Tp, _Alloc>::iterator vector<_Tp, _Alloc>:: emplace(iterator __position, _Args&&... __args) { const size_type __n = __position - begin(); if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage && __position == end()) { this->_M_impl.construct(this->_M_impl._M_finish, std::forward<_Args>(__args)...); ++this->_M_impl._M_finish; } else _M_insert_aux(__position, std::forward<_Args>(__args)...); return iterator(this->_M_impl._M_start + __n); }
关键成员变量说明
先搞懂vector底层的几个核心指针:
_M_impl._M_start:指向底层动态数组的第一个元素_M_impl._M_finish:指向当前已存元素的下一个位置(对应vector的size)_M_impl._M_end_of_storage:指向底层数组的最后一个位置的下一位(对应vector的capacity)
代码逐行解析
记录插入位置偏移
const size_type __n = __position - begin();计算插入位置相对于数组起始点的偏移量。后续如果发生扩容,原迭代器会失效,用这个偏移量可以生成新的有效迭代器。
快速路径判断
if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage && __position == end())这是性能优化的核心分支,只有同时满足两个条件才会走这条最快的路径:
- 容器还有剩余容量(
_M_finish != _M_end_of_storage,即size < capacity) - 插入位置是容器末尾(
__position == end())
- 容器还有剩余容量(
快速路径执行
- 原地构造元素:
调用分配器的construct方法,在this->_M_impl.construct(this->_M_impl._M_finish, std::forward<_Args>(__args)...);_M_finish指向的空位置原地构造新元素。std::forward是完美转发,保证传入的参数左/右值属性不丢失,最大化构造效率。 - 更新元素数量指针:
把++this->_M_impl._M_finish;_M_finish往后移一位,标记新元素已加入。
- 原地构造元素:
通用路径处理
else _M_insert_aux(__position, std::forward<_Args>(__args)...);只要不满足快速路径的条件(比如在中间插入,或者容器已满需要扩容),就交给
_M_insert_aux函数处理,它会完成:- 若容器已满,自动扩容(分配更大的新数组,批量移动/拷贝旧元素)
- 将插入位置后的所有元素向后移动一位,腾出空间
- 在目标位置原地构造新元素
- 更新容器的size和指针
返回有效迭代器
return iterator(this->_M_impl._M_start + __n);用之前记录的偏移量
__n,从当前数组起始位置生成迭代器返回。避免了扩容后原迭代器失效的问题。
自定义vector emplace慢的可能原因
你的直觉(扩容时移动对象)没错,但GCC的实现做了末尾插入的快速路径优化:当插入到末尾且有剩余容量时,完全不需要移动任何元素,直接原地构造。如果你的自定义实现没有这个分支,每次插入都走扩容检查或元素移动,性能自然会差。另外_M_insert_aux里的扩容和元素移动也有批量优化(比如用移动语义代替拷贝),这些细节也会影响性能。
内容的提问来源于stack exchange,提问作者fettahyildiz
相关产品推荐
相关产品推荐

