zoukankan      html  css  js  c++  java
  • 滥用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;瓶颈消失。

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

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

  • 相关阅读:
    信号signal的监听与处理
    oracle 12cR1&12cR2核心高实用性新特性
    Tomcat 7服务器线程模型
    抓取awr、语句级awr、ashrpt
    从percona server 5.7换到mariadb 10.2
    关于typeid和typeof
    mysql查询INFORMATION_SCHEMA表很慢的性能优化
    使用ccache大幅度加速gcc编译速度至少1倍以上(不需要修改任何编译选项)
    c++ linux下输出中文
    visual studio 2015下使用gcc调试linux c++开发环境搭建完整详解
  • 原文地址:https://www.cnblogs.com/itZhy/p/2709374.html
Copyright © 2011-2022 走看看