当前位置:  开发笔记 > 编程语言 > 正文

从char*初始化std :: string而不复制

如何解决《从char*初始化std::string而不复制》经验,为你挑选了3个好方法。

我有一种情况,我需要处理大量(许多GB)的数据量:

    通过附加许多较小的(C char*)字符串来构建一个大字符串

    修剪弦乐

    将字符串转换为C++ const std :: string进行处理(只读)

    重复

每次迭代中的数据都是独立的.

我的问题是,我想最小化(如果可能消除)堆分配的内存使用量,因为它目前是我最大的性能问题.

有没有办法将C字符串(char*)转换为stl C++字符串(std :: string),而不需要std :: string来内部分配/复制数据?

或者,我可以使用stringstreams或类似的东西来重用大缓冲区吗?

编辑:感谢您的回答,为清楚起见,我认为修改后的问题将是:

如何有效地构建(通过多个附加)一个stl C++字符串.如果在循环中执行此操作,其中每个循环完全独立,我如何重新使用此分配的空间.



1> puetzk..:

在不复制数据的情况下,实际上无法形成std :: string.字符串流可能会重用从传递到传递的内存(虽然我认为标准是否真的必须是静音),但它仍然无法避免复制.

解决此类问题的一种常见方法是编写在步骤3中处理数据的代码,以使用开始/结束迭代器对; 然后它可以轻松处理std :: string,chars向量,一对原始指针等.与传递类似std :: string的容器类型不同,它将不再知道或关心内存的分配方式,因为它仍然属于来电者.将这个想法运用到它的逻辑结论是boost :: range,它将所有重载的构造函数添加到仍然让调用者只传递一个字符串/ vector/list /任何类型的容器与.begin()和.end(),或者分开迭代器.

编写了处理代码以处理任意迭代器范围后,您甚至可以编写自定义迭代器(不像听起来那么难,基本上只是一个带有一些标准typedef的对象,以及operator ++/*/=/==/!=重载以获得一个仅向前的迭代器),每当它到达它正在处理的那个片段的末尾时,它会负责前进到下一个片段,跳过空格(我假设这是你修剪的意思).你根本不需要连续组装整个字符串.这是否会取胜取决于你拥有多少片段/片段大小.这基本上是Martin York提到的SGI绳索:一个字符串,其中append形成一个链接的片段列表而不是一个连续的缓冲区,因此适用于更长的值.


更新(因为我仍然看到这个答案的偶尔投票):

C++ 17引入了另一种选择:std :: string_view,它在许多函数签名中替换了std :: string,是对字符数据的非拥有引用.它可以从std :: string隐式转换,但也可以从其他地方拥有的连续数据显式构造,避免不必要的复制std :: string强制.



2> e.James..:

是否可以在步骤1中使用C++字符串?如果使用string::reserve(size_t),可以分配足够大的缓冲区以防止多个堆分配,同时附加较小的字符串,然后您可以在所有剩余步骤中使用相同的C++字符串.

有关该reserve功能的更多信息,请参阅此链接.



3> Martin York..:

为了帮助实现真正的大字符串,SGI在其STL中拥有类Rope.
非标准但可能有用.

http://www.sgi.com/tech/stl/Rope.html

显然绳索是标准的下一个版本:-)
请注意开发人员的笑话.绳子是一根大绳子.(哈哈) :-)

推荐阅读
coco2冰冰
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有