导读:在百度看似简简单单的界面后面,是遍布全国的各个数据中心里,运转着的海量C++服务。如何提升性能,降低延时和成本就成了百度C++工程师的必修功课。伴随着优化的深入攻坚,诞生并积累下来一系列的性能优化理论和方案,其中不乏一些冷门但精巧实用的经验和技巧。本文从内存访问角度,收集总结了一些具有通用意义的典型案例,分享出来和大家学习交流。
背景
在百度看似简简单单的界面后面,是遍布全国的各个数据中心里,运转着的海量C++服务。对C++的重度应用是百度的一把双刃剑,学习成本陡峭,指针类错误定位难、扩散性广另很多开发者望而却步。然而在另一方面,语言层引入的额外开销低,对底层能力可操作性强,又能够为追求极致性能提供优异的实践环境。
因此,对百度的C++工程师来说,掌握底层特性并加以利用来指导应用的性能优化,就成了一门必要而且必须的技能。久而久之,百度工程师就将这种追求极致的性能优化,逐渐沉淀成了习惯,甚至形成了对技术的信仰。下面我们就来盘点和分享一些,在性能优化的征途上,百度C++工程师积累下来的理论和实践,以及那些为了追求极致,所发掘的『奇技淫巧』。
重新认识性能优化作为程序员,大家或多或少都会和性能打交道,尤其是以C++为主的后端服务工程师,但是每个工程师对性能优化概念的理解在细节上又是千差万别的。下面先从几个优化案例入手,建立一个性能优化相关的感性认识,之后再从原理角度,描述一下本文所讲的性能优化的切入角度和方法依据。
.从字符串处理开始..stringasabuffer为了调用底层接口和集成一些第三方库能力,在调用界面层,会存在对C++字符串和C风格字符串的交互场景,典型是这样的:
size_tsome_c_style_api(char*buffer,size_tsize);voidsome_cxx_style_function(std::stringresult){//首先扩展到充足大小result.resize(estimate_size);//从c++7开始,string类型支持通过data取得非常量指针autoacture_size=some_c_style_api(result.data(),result.size());//最终调整到实际大小result.resize(acture_size);}
这个方法存在一个问题,就是在首次resize时,string对estimate_size内的存储区域全部进行了0初始化。但是这个场景中,实际的有效数据其实是在some_c_style_api内部被写入的,所以resize时的初始化动作其实是冗余的。在交互buffer的size较大的场景,例如典型的编码转换和压缩等操作,这次冗余的初始化引入的开销还是相当可观的。
为了解决这个问题,大约从年前开始,已经有人在持续尝试推动标准改进。