std字符串串联性能
std string concatenation performance
在性能方面,现代C++
编译器中的以下函数有什么区别吗?
std::string ConcatA(const std::string& a, const std::string& b, const std::string& c)
{
return a + b + c;
}
std::string ConcatB(const std::string& a, const std::string& b, const std::string& c)
{
std::string r = a;
r += b;
r += c;
return r;
}
ConcatB有1个临时字符串,而ConcatA有2个临时字符串。因此,ConcatB的速度是前者的两倍。
$cat cata.cpp
#include <string>
#include <iostream>
std::string ConcatA(const std::string& a, const std::string& b, const std::string& c)
{
return a + b + c;
}
int main(){
std::string aa="aa";
std::string bb="bb";
std::string cc="cc";
int count = 0;
for(int ii = 0; ii < 10000000; ++ii) {
count += ConcatA(aa, bb, cc).size();
}
std::cout<< count <<std::endl;
}
$cat catb.cpp
#include <string>
#include <iostream>
std::string ConcatB(const std::string& a, const std::string& b, const std::string& c)
{
std::string r = a;
r += b;
r += c;
return r;
}
int main(){
std::string aa="aa";
std::string bb="bb";
std::string cc="cc";
int count = 0;
for(int ii = 0; ii < 10000000; ++ii) {
count += ConcatB(aa, bb, cc).size();
}
std::cout<< count <<std::endl;
}
$clang++-v
Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin13.1.0
Thread model: posix
$ clang++ cata.cpp
$ time ./a.out
60000000
real 0m1.122s
user 0m1.118s
sys 0m0.003s
$ clang++ catb.cpp
$ time ./a.out
60000000
real 0m0.599s
user 0m0.596s
sys 0m0.002s
$
我用MinGW(TDM)4.8.1编译了它,并优化了选项-fdump树,没有-O2
第一个像一样移动
string tmp = a+b; // that mean create new string g, g += b, tmp = g (+dispose g)
tmp += c;
return tmp; // and dispose tmp
第二种方法是
string tmp = a; // just copy a to tmp
tmp += b;
tmp += c;
return tmp; // and dispose tmp
它看起来就像这个
void * D.20477;
struct basic_string D.20179;
<bb 2>:
D.20179 = std::operator+<char, std::char_traits<char>, std::allocator<char> > (a_1(D), b_2(D)); [return slot optimization]
*_3(D) = std::operator+<char, std::char_traits<char>, std::allocator<char> > (&D.20179, c_4(D)); [return slot optimization]
<bb 3>:
<bb 4>:
std::basic_string<char>::~basic_string (&D.20179);
D.20179 ={v} {CLOBBER};
<L1>:
return _3(D);
<L2>:
std::basic_string<char>::~basic_string (&D.20179);
_5 = __builtin_eh_pointer (1);
__builtin_unwind_resume (_5);
和
void * D.20482;
struct string r [value-expr: *<retval>];
<bb 2>:
std::basic_string<char>::basic_string (r_1(D), a_2(D));
std::basic_string<char>::operator+= (r_1(D), b_3(D));
<bb 3>:
std::basic_string<char>::operator+= (r_1(D), c_4(D));
<bb 4>:
<L0>:
return r_1(D);
<L1>:
std::basic_string<char>::~basic_string (r_1(D));
_5 = __builtin_eh_pointer (1);
__builtin_unwind_resume (_5);
因此,在应用-O2优化编译器后,将ConcatB函数保持在几乎相同的视图中,并通过内联函数、向内存分配部分添加常数值、声明新函数来使用ConcatA,但最有价值的部分保持不变。
ConcatA:
D.20292 = std::operator+<char, std::char_traits<char>, std::allocator<char> > (a_2(D), b_3(D)); [return slot optimization]
*_5(D) = std::operator+<char, std::char_traits<char>, std::allocator<char> > (&D.20292, c_6(D));
ConcatB:
std::basic_string<char>::basic_string (r_3(D), a_4(D));
std::basic_string<char>::append (r_3(D), b_6(D));
std::basic_string<char>::append (r_3(D), c_8(D));
因此,很明显,ConcatB比ConcatA更好,因为它做的分配操作更少,当你试图优化这么小的代码片段时,这是非常昂贵的。
相关文章:
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 通过默认复制构造函数比较 C++ 字符串是否会影响性能,原因为何?
- 性能 - 使用字符串构造函数与使用串联
- C++和Java的字符串循环性能比较
- 检查从查询返回的任何行是否包含在字符串中的最高性能方法?
- MongoC ++驱动程序BSON构造:基于流与基于字符串解析.哪一个性能更好?
- STD ::移动性能,同时将大字符串作为rvalue
- C++按字符串调用函数,比较PHP的性能,如何在C++中优化代码
- 性能字符串作为函数参数
- C++字符串构造性能
- 字符串操作性能问题
- 字符串与哈希作为映射键 - 性能
- 通过 iStringStream 标记化的 C++ 字符串的性能开销
- 对于静态错误字符串,哪个的内存/性能效率更高,或者有替代方案
- std::用于处理短字符串的字符串性能
- 在将 char 数组复制到字符串期间节省 CPU 周期(提高性能)
- 性能字符串与字符串
- C++代码性能字符串进行比较
- 性能标准::strstr vs. 标准::字符串::查找
- [ 性能]--- 字符串::运算符+= 与向量<char>push_back