滥用vector带来的瓶颈

手中的项目逼近后期,大多做一些性能调优的事情,最近发现了一个滥用vector带来的性能问题,跟大家分享一下。

问题的场景是这样的:

在一组循环的内部(循环次数很多),有一个计算模块,用以计算每次循环条件下某个指标的值。郁闷的是,这组循环计算的性能老是不达标,循环执行需要10s左右的时间,通过调试逐步定位瓶颈,发现下面的代码尽然消耗了2s多的时间,占总计算时间的百分之20多!

vector<double> tmp(2, 0);

调试过程中统计过,一行长长的复杂数学运算(比如sqrt(a * b / c + d^2 + sin(e) + atan(b)) ),循环执行同样次数,耗时都不到1s,上面这行仅仅是定义一个vector竟有如此大的威力。

STL在带给我们方便的同时,也隐藏了大量实现细节,vector的内部实现是一个动态数组,其数据缓冲区是在运行时是从堆上new出来的。

堆申请空间的效率比栈要低的多,具体原因主要在于:栈上的内存地址分配在编译时就已经完成了,执行的时候只是用编译时确定的地址直接存取即可(可执行文件一运行,进程空间中就有固定的若干M的栈空间)。而堆上内存分配在运行时完成的,且有一套复杂的算法,比如C++的new会先在该进程目前的堆中搜索足够大的可用空间,如果搜索不到,还要通过系统调用向操作系统申请更大的堆空间,这样一来二去的,如果仅仅为了2个double的简单存取(即不考虑数组长度扩展),实在是不划算。

将vector<double> tmp(2, 0);修改为double tmp[2]; tmp[0] = 0; tmp[1] = 0;瓶颈消失。

这个问题其实比较简单,不过给了我一个实际的机会,体验到堆的效率比栈慢的多,之前都是看书上这么写的,没有直接的感官刺激,相信今后在写代码的时候,这种感觉会成为设计直觉的一部分,不知不觉中发挥重大作用。

这里也体现了敏捷开发中的一个重要思想,书写刚刚好的代码,这“刚刚好”三个字,也在于能用简单数据结构搞定的事情,就不要急着用复杂的数据结构搞定。

原文链接: https://www.cnblogs.com/itZhy/archive/2012/09/30/2709374.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    滥用vector带来的瓶颈

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/64310

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月9日 上午11:23
下一篇 2023年2月9日 上午11:23

相关推荐