一、概述
Folly的全称Facebook Open-source Library,目的不是为了替代标准库,而是对标准库的一种补充,提供了许多高性能的组件,如Fbstring、FbVector等。folly库常作为FaceBook其他开源c++的依赖。
二、安装&使用
2.1 获取folly
folly是facebook开源底层库,托管在github上面,可以从github上获取源码并进行本地编译。
git clone https://github.com/facebook/folly
2.2 编译folly
值得注意的是,folly默认编译产物是静态链接库,可以通过设置编译选项-DFOLLY_SUPPORT_SHARED_LIBRARY=ON编译产出动态库,但是可能会很大。关于为什么编译产出为静态库,项目readme给出的原因如下:
# Install dependencies
cd folly
sudo ./build/fbcode_builder/getdeps.py install-system-deps --recursive
# compiler
mkdir _build && cd _build
cmake ../
make -j4
sudo make install
folly内部的某些实现可能会依赖fmt v10.0,可以通过以下方式安装fmt
git clone https://github.com/fmtlib/fmt.git
cd fmt
mkdir build
cd build
cmake ..
make
sudo make install
2.3 使用
正如开源项目所说,folly是对标准库的补充,在标准库中的相关组件的性能无法满足项目需求时,folly才会着手开发,因此fbvector与C++标准库中的vector使用方式相同
#include<folly/FBVector.h>
folly::fbvector<int> numbers({0, 1, 2, 3});
numbers.reserve(10);
for (int i = 4; i < 10; i++) {
numbers.push_back(i * 2);
}
assert(numbers[6] == 12);
三、性能分析
根据开源项目FBVector.md描述,fbvector相较于标准库的vector主要进行两部分的优化:扩容因子(growth factor)和分配器算法(jemalloc)。
3.1 扩容因子
为了避免二次分配,std::vector分配的内存通常呈指数增长,小的扩容因子会导致频繁扩容,大的扩容因子会导致vector消耗过多的内存。
gcc编译器默认的扩容因子是2,这个数值会导致每次扩容新申请的空间大小总是大于之前所有使用过的的内存。但是1.5的扩容因子在4次重新分配后可以使用之前释放的内存,fbvector使用的就是1.5的扩容因子。仅仅是扩容因子的改变并不能显著提升vector的性能(Visual C++使用的扩容因子也是1.5),fbvector对vector的优化还体现在分配器上。
3.2 jemalloc
分配器处在用户程序和内核之间,它响应用户的分配请求,向操作系统申请内存,然后将其返回给用户程序。业界常见的库包括:ptmalloc(glibc标配)、tcmalloc(google)、jemalloc(facebook)。
C++标准库默认使用的是ptmalloc(Per thread malloc)算法,该算法是glibc默认分配算法具有很好的平台兼容性,但是其并发能力弱,分配内存时加锁操作也极大限制了分配效率,同时也更容易产生内存碎片。tcmalloc(Thread caching malloc)是Google开源的一款分配器,优化了ptmalloc的并发性能。
jemalloc是Jason Evans于2005年开发的,侧重于减少内存碎片和提升多线程高并发场景下内存的分配效率。与其它内存分配器相比,它最大的优势在于多线程情况下的高性能以及内存碎片的减少。
3.3 benchmark
使用Google benchmark对比std vector和fbvector的push_back()的性能。对比结果如下,bool标志位表示为是否使用的是std vector,false时使用fbvector:
3.4 总结
无论从理论实现上还是性能测试中,fbvector的性能均优于std vector;fbvector对内存管理上更加细粒,并且fbvector也广泛应用于一些对性能要求较高的工程上面。但是有一些问题值得注意:
- folly依赖于C++14,对于一些低版本的C++项目适配可能会存在问题;
- folly编译产物默认是静态链接库,在一定程度上会增加可执行文件的内存,也不利于OTA;
关于第二点,项目ISSUE中也有讨论,可能在真正使用中应该进行一些必要的评估。
四、参考链接
GitHub - facebook/folly: An open-source C++ library developed and used at Facebook.
内存管理特性分析(十五):内存分配器之jemalloc技术原理分析 - 知乎