了解std :: string的效率

时间:2011-04-23 21:54:57

标签: c++ string performance construction

我正在尝试更多地了解c ++字符串。

考虑

const char* cstring = "hello";
std::string string(cstring);

std::string string("hello");

我是否正确假设两者都在应用程序的.data部分中存储“hello”,然后将字节复制到堆上的另一个区域,由std :: string管理的指针可以访问它们?

我怎样才能有效地存储一个非常长的字符串?我正在考虑从套接字流中读取数据的应用程序。我担心连续多次。我可以想象使用链表并遍历此列表。

Strings已经吓倒了我太久了!

任何链接,提示,解释和进一步的细节都会非常有用。

4 个答案:

答案 0 :(得分:2)

我已经存储了10个或100个MB范围内的字符串而没有问题。当然,它主要受可用(连续)内存/地址空间的限制。

如果你要追加/连接,有一些事情可能有助于提高效率:如果可能的话,尝试使用reserve()成员函数来预先分配空间 - 即使你有一个粗略的关于最终大小可能有多大的想法,随着字符串的增长,它将免于不必要的重新分配。

此外,许多字符串实现使用“指数增长”,这意味着它们增长了一些百分比,而不是固定的字节大小。例如,它可能只需要在需要额外空间时将容量加倍。通过以指数方式增加大小,执行大量连接变得更有效。 (具体细节取决于您的stl版本。)

最后,另一个选项(如果你的库支持它)是使用 rope<> 模板:Ropes类似于字符串,除了它们在对非常大的字符串执行操作时效率更高。特别是,“绳索以小块分配,显着减少了大块引入​​的内存碎片问题”。关于SGI's STL guide的一些其他详细信息。

答案 1 :(得分:2)

由于您正在从套接字读取字符串,因此可以重用相同的数据包缓冲区并将它们链接在一起以表示巨大的字符串。这将避免任何不必要的复制,并且可能是最有效的解决方案。我似乎记得ACE库提供了这样一种机制。我会试着找到它。

编辑: ACE具有ACE_Message_Block,允许您以链表方式存储大型邮件。您几乎需要阅读C ++网络编程书籍才能理解这个庞大的库。 ACE网站上的免费教程非常糟糕。

我敢打赌Boost.Asio必须能够做与ACE的消息块相同的事情。 Boost.Asio现在似乎比ACE有更大的思想共享,所以我建议首先在Boost.Asio中寻找解决方案。如果有人能够启发我们关于Boost.Asio解决方案,那就太棒了!


现在是时候我尝试使用Boost.Asio编写一个简单的客户端 - 服务器应用程序来查看所有大惊小怪。

答案 2 :(得分:0)

我不认为效率应该是问题。两者都表现得很好。

这里的决定因素是封装。 std::string是一个比char *更好的抽象。封装指针算法是一件好事。

许多人认为很长很难以提出std::string。我认为未能将其用于毫无根据的效率原因是愚蠢的。坚持更好的抽象和封装。

答案 3 :(得分:0)

您可能知道,an std::string is really just another name for basic_string<char>.

也就是说,它们是一个序列容器,内存将按顺序分配。如果您尝试使一个大于您可以分配的可用连续内存,则可以从std :: string获取异常。由于内存碎片,此阈值通常远小于可用内存总量。

我在尝试分配例如图像的大型连续3D缓冲区时看到了分配连续内存的问题。但至少在我的经验中,这些问题至少在100MB左右的时候才开始发生,例如在Windows XP Pro上。(例如。)

你的琴弦这么大吗?