C++ 为什么某些类型的字符串连接比其他类型的要快得多?

C++ 为什么某些类型的字符串连接比其他类型的要快得多?,c++,string,C++,String,考虑以下四种情况: #include <string> int main() { std::string s("Hi I'm Da"); 1. s += "n"; 2. s += 'n'; 3. s = s + "n"; 4. s = s + 'n'; return 0; } 使用g++版本4.8.3 20140624,我得到以下结果: 2.16172ms 0.48296ms 510.202ms 510.455ms 现在我可以理解,+=更快,因为在分配

考虑以下四种情况:

#include <string>
int main()
{
    std::string s("Hi I'm Da");

 1. s += "n";
 2. s += 'n';
 3. s = s + "n";
 4. s = s + 'n';

    return 0;
}
使用g++版本4.8.3 20140624,我得到以下结果:

2.16172ms
0.48296ms
510.202ms
510.455ms
现在我可以理解,
+=
更快,因为在分配任务之前,您没有使用
+
进行复制,但是为什么案例1和案例2与案例3和案例4相比有显著差异?另外,使用双引号或单引号如何影响连接速度

s += "n";
这将对在位的字符串进行操作。可能不需要重新分配内存。但是字符串文字是以零结尾的字符序列,因此代码需要在内存中找到“n”之后的0值

s += 'n';
这与第一个类似,但它使用字符文字而不是字符串文字。无需搜索0,因此速度可能更快

s = s + "n";
搜索0是存在的,但更重要的是,必须构造新的临时字符串对象,很可能这意味着内存分配,这是数量级或更昂贵的

s = s + 'n';
可能比上一个更快,但与堆上的临时对象创建和分配相比,搜索0所造成的差异很可能可以忽略不计


注意所有“可能”和“可能”。我所描述的可能发生在流行的编译器中,但各种优化可能会完全改变情况。

对于字符串文字,代码需要搜索空终止符。对于字符文字,只有一件事可以做,没有分支。赋值会在右边产生一个临时对象。它们实际上可以使用字符串文本的重载来捕获编译时的长度。。。这会加快一些速度。@嗨,我是丹:你指的是单引号和双引号,好像它们是某种装饰性的功能。实际上,它们的意思完全不同
“n”
是C样式的字符串,而
'n'
根本不是字符串,而是单个字符。难怪它们是由完全不同的代码分支处理的,这些分支针对不同的一般情况进行了优化。gcc字符串是否仍然在写时进行复制?或者它们现在符合C++11标准了吗?@AdrianMcCarthy:在这里查找:状态部分,不符合COW实现。(最新的GCC,V4.9.1)最后一段非常关键,因为它们都具有完全相同的可观察行为,因此可以根据完全相同的指令进行优化。(只是想强调一下。)
s = s + 'n';