如果频繁地连接字符串以形成最终结果,那么最好的做法是什么?( C++11或更高版本)
那么string::append()或ostringstream呢?
还有另一个问题:如果我使用许多+连接字符串,现代编译器会以最有效的方式优化它吗?(就像Java现在可以使用StringBuilder优化字符串连接一样)
发布于 2018-07-10 18:02:44
万一你在人为的领域里想到了StringBuilder。
您可以使用字母表(Google)库,ABCLib,ABCL或只是ABCL。
https://abseil.io/docs/cpp/guides/strings向前看并立即分配它所需的一切,然后按照您的需要在其中构建字符串。对于concat作业,只需要absl::StrCat()和absl::StrAppend()。
我不擅长解释事情。也许下面这个https://godbolt.org/g/V45pXJ链接可能比我讲得更好。
了解更多关于YouTube:https://www.youtube.com/watch?v=xu7q8dGvuwk&t=32m (ffw到32分钟)的信息
youtube.com/watch?v=xu7q8dGvuwk&t=32m
#include <string>
#include <iostream>
#include <absl/strings/str_cat.h>
int main()
{
std::string s1,s2,s3,s4,
s5,s6,s7,s8,
s9,s10,s11,s12;
std::getline(std::cin, s1);
std::getline(std::cin, s2);
std::getline(std::cin, s3);
std::getline(std::cin, s4);
std::getline(std::cin, s5);
std::getline(std::cin, s6);
std::getline(std::cin, s7);
std::getline(std::cin, s8);
std::getline(std::cin, s9);
std::getline(std::cin, s10);
std::getline(std::cin, s11);
std::getline(std::cin, s12);
std::string s = s1 + s2 + s3 + s4 + // a call to operator+ for each +
s5 + s6 + s7 + s8 +
s9 + s10 + s11 + s12;
// you shall see that
// a lot of destructors get called at this point
// because operator+ create temporaries
std::string abseil_s =
absl::StrCat(s1,s2,s3,s4, // load all handles into memory
s5,s6,s7,s8, // then make only one call!
s9,s10,s11,s12);
return s.size() + abseil_s.size();
// you shall see that
// only "real" s1 - s12 get destroyed
// at these point
// because there are no temporaries!
}
更新2021
现在,您也可以在fmt:format或std::format实现完成时使用c++20 图书馆。(当前的fmtlib现在将支持插入到c++14。)
format会像The StrCat那样向前看,所以不会浪费时间。
string fmt_s =
fmt::format("{}{}{}{}{}{}{}{}{}{}{}{}",
s1,s2,s3,s4, // load all handles into memory
s5,s6,s7,s8, // then make only one call!
s9,s10,s11,s12);[活着]
发布于 2018-07-10 16:34:03
如果您不需要std::ostringstream的任何特性,那么如果您的最终目标是获得单个std::string (事先充分调用reserve可能会减少一些无用的分配),那么向同一个字符串添加普通字符串通常是最有效的方法。在内部,std::ostringstream的工作方式大致相同,但它为额外的层增加了一些开销。
还有另一个问题:如果我使用许多
+连接字符串,现代编译器会以最有效的方式优化它吗?(就像Java现在可以使用StringBuilder优化字符串连接一样)
std::string已经有点像StringBuilder了,因为它是一种有效增长的可变类型,因此您不需要为此使用不同的类型。
现在,在C++03中,多个级联的+将创建所有相关的临时字符串,因此如果要保持效率,就必须在目标字符串上显式地使用+=。
OTOH,C++11添加了带有rvalue引用的operator+重载,这允许为下一次连接回收/扩展临时字符串的分配存储空间,因此在大多数情况下效率应该是可比的--感谢@Daniel指出了这一点。
我认为有一种情况是这样的,那就是:
big_string += a + b + c;在这种情况下,a + b + c本身是高效计算的,但是没有考虑到它将被附加到另一个字符串(因此,可能没有任何额外的分配)。你最好还是用“传统”方法,或者用
big_string = std::move(big_string) + a + b + c;https://stackoverflow.com/questions/51270175
复制相似问题