引言
这个问题是在个人处理HTTP响应头的时候突然冒出来的。因为我需要分割以CRLF结尾的各个参数,函数声明是这样的std::string retrieveUntilCRLFAsString(const char*)
。每一次都要分割为std::string类型,都有一次拷贝的资源消耗,但这个资源开销有多大呢?这让我对string的性能产生了好奇。
std::string实现方式
COW
COW,也就是写时拷贝,是一种编译器级别上的优化手段,目的是为了减少一些无意义的深拷贝开销。
据我了解,在g++4.5版本上,std::string使用了COW实现,但在5.0后就改用SSO了。原因是COW会导致BUG并且多线程情况下性能比较差劲。
bug的是在COW实现的情况会产生Dangling pointer(悬空指针),在StackOverFlow上有着详细的例子Legality of COW std::string implementation in C++11
性能差劲的问题在Concurrency Modifications to Basic String进行了讲解。从而提议禁用COW。
SSO
SSO(Small String Optimization)中文直译就是小字符串优化。
原理是申请堆内存的开销比较大,因此,短的字符串会被申请在栈上。
Meaning of acronym SSO in the context of std::string对SSO进行了详细介绍。
最后
了解了COW和SSO后,我决定还是怪怪的乖乖的去分割char*吧,免得造成不必要的开销。
另外c++深挖起来可真是深奥,一个string的实现能有这样的操作。顺便给自己定一个小目标,等秋招和毕设搞定后一定要看看《STL源码剖析》这本书。