字符串+ = s1和字符串=字符串+ s1之间的区别

Nam*_*man 28 c++ performance stdstring compound-assignment

我的程序之一超出了我使用的时间限制fans = fans + s[i],而当我正在使用fans += s[i]它的时候却被接受了……为什么会发生这种情况?为了进一步说明,迷是一个字符串,而s也是一个字符串,因此在遍历字符串si时只需要s的一些字符,因此我创建了一个新的字符串迷。现在有两种方法可以在新字符串中添加字符粉丝 问题在下面提到

fans = fans + s[i]; // gives Time limit exceeded 
fans += s[i];       // runs successfully
Run Code Online (Sandbox Code Playgroud)

Ayx*_*xan 29

对于内置类型, a += b它与完全相同a = a + b,但是对于类,这些运算符会重载并调用不同的函数。
在您的示例中,fans = fans + s[i]创建一个临时字符串,并将其分配(移动)到fans,但fans += s[i]不会创建该临时字符串,因此它可能会更快。

  • 如果字符串大小已经与预分配的缓冲区一样大,则“ + =”也可能导致重定位。如果后来发现这是一个问题(当然应该对此进行衡量),并且如果可以预先估计大小,则可以使用string :: reserve()显式增加缓冲区大小。 (3认同)

Who*_*aig 12

std::string有成员operator +operator +=。前者通常通过中间临时方式与后者实现。有效地看起来像这样(如果您想确切地知道自己的工作,请检查实现源):

/// note reference return type
std::string& operator +=(char c) 
{
    this->append(c);
    return *this;
}

// note value return type
std::string operator +(char c) const
{
    std::string tmp = *this;
    tmp += c; // or just tmp.append(c) directly
    return tmp;
}
Run Code Online (Sandbox Code Playgroud)

的设置tmp非常昂贵。通过将移动分配语义转移到调用方的最终目的地,可以(并且通常是)使整体功能更好,但是临时开销仍然存在。这样做几次,您将不会注意到差异。做数千或数百万次,这可能意味着世界不同。


小智 11

如果使用fans=fans+s[i],则该字符串将在每次循环传递中复制。新元素将添加到字符串的副本中,结果将重新分配给变量fans。在此之后,将不得不删除旧字符串,因为它不再被引用。这需要大量时间。

如果使用扩充分配fans+=s[i],则不会在每次循环遍历中都复制该字符串,并且无需删除参考变量,因为此处没有参考变量。这样可以节省大量时间。

我希望你现在能理解!