最近在分析算子的火焰图数据,发现了比较多的std::vector::push_back操作,想着这里是否也可以优化一把。
必须了解几个事实。vector的容量(内存)永远不会减少,即使调用 clear 方法,除非使用swap 方法。(C++11 语言提供了shrink_to_fit方法修复。)STL vector的另一个棘手问题是有很多方法可以构建。可以用 new或者push_back。
那么这些有啥区别呢?
push_back
除了把数据push进容器,还会对容器内存size大小做边界检查。如果容器没有空间储存新的元素,还会对容器内存进行一次扩容。我门都知道扩容是容器去系统找一份更大的内存地址,然后把元素拷贝过去。所以这里经常会用reserver去预分配内存,避免扩容操作。而操作符operator[]
只是做一些地址寻找,然后在地址上填充数据。看起来不是很安全。
而且这里即时用reserver保留了空间,push_back
也会进行额外的条件检查,而这种检查是operator[]
不会有的。此外,而且push_back增加size
值(reserve 只设置capacity
),因此每次都会更新。
简而言之,push_back
做的比做的多operator[]
——这就是为什么它更慢(更准确)。
这里stackoverflow线程还讨论更多的扩展点,一个比较有意思的地方就是相比于单纯的new之后执行operator[],额外进行一次memset竟然会减少之后的处理时间。这跟系统内存页管理机制有关系。https://stackoverflow.com/questions/20168051/why-push-back-is-slower-than-operator-for-a-previously-allocated-vector
这里的代码也做了相应的修改。在预先知道要插入元素数量的前,事先做resize操作,然后使用operator[]。当然并不能说一定能达到明显的系统优化,但是至少对这个函数来说,有改进了一些。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。