c++ - C++14如何提高 "str1 + str2 + str3 + ..."的效率?

标签 c++ c++11 move-semantics rvalue-reference ref-qualifier

std::string Concatenate(const std::string& s1,
                        const std::string& s2,
                        const std::string& s3,
                        const std::string& s4,
                        const std::string& s5)
{
    return s1 + s2 + s3 + s4 + s5;
}

默认情况下,return s1 + s2 + s3 + s4 + s5; 可能等同于以下代码:

auto t1 = s1 + s2; // Allocation 1
auto t2 = t1 + s3; // Allocation 2
auto t3 = t2 + s4; // Allocation 3

return t3 + s5; // Allocation 4

有没有一种优雅的方法可以将分配次数减少到 1 次?我的意思是保持 return s1 + s2 + s3 + s4 + s5; 不变,但效率会自动提高。如果可能的话,也可以避免程序员误用std::string::operator +

ref-qualifier 成员函数有帮助吗?

最佳答案

问题的前提是:

s1 + s2 + s3 + s4 + s5 + ... + sn

将要求 n 个分配不正确。

相反,它将需要 O(Log(n)) 分配。第一个 s1 + s1 将生成一个临时文件。随后,临时(右值)将成为所有后续 + 操作的左参数。该标准规定,当 string + 的 lhs 是右值时,实现只需附加到该临时值并将其移出:

operator+(basic_string<charT,traits,Allocator>&& lhs,
          const basic_string<charT,traits,Allocator>& rhs);

Returns: std::move(lhs.append(rhs))

该标准还规定字符串的容量将呈几何级数增长(1.5 到 2 之间的倍数很常见)。因此,在每次分配时,容量都会呈几何级数增长,并且该容量会沿着 + 操作链传播。更具体地说,原始代码:

s = s1 + s2 + s3 + s4 + s5 + ... + sn;

实际上等同于:

s = s1 + s2;
s += s3;
s += s4;
s += s5;
// ...
s += sn;

当几何容量增长与短串优化相结合时,“预留”正确容量的值(value)是有限的。只有当此类代码在您的性能测试中实际显示为热点时,我才会费心这样做。

关于c++ - C++14如何提高 "str1 + str2 + str3 + ..."的效率?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25755297/

相关文章:

C++ 使用传递函数

c++ - 为什么我的线程永远不会结束

c++ - 为什么不使用 `make_x()` 函数尽可能省略 move 构造函数?

c++ - 为什么我的词法分析器无法识别引号 ""

c++ - 在 C++.NET 中使用 OpenGL 并在视口(viewport)上绘制

c++ - 无法在 Xcode 4 c++ 工具中打开文本文件资源?

c++ - 如何在结构的方法之一中将结构成员作为默认参数传递?

c++ - std::upper_bound 在 const 成员函数中返回 const 迭代器

c++ - 无限制 union 的 move 构造函数因 invalid_pointer 而崩溃

c++ - 使用 std::move() 创建右值引用变量是否有任何用处。 [C++]