gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:24:25 29 4
gpt4 key购买 nike

我遇到这样一种情况,我需要处理大量(许多 GB)数据:

  1. 通过附加许多较小的 (C char*) 字符串构建一个大字符串
  2. 修剪字符串
  3. 将字符串转换为C++ const std::string进行处理(只读)
  4. 重复

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

我的问题是,我想尽量减少(如果可能的话消除)堆分配的内存使用量,因为目前这是我最大的性能问题。

有没有一种方法可以将 C 字符串 (char*) 转换为 STL C++ 字符串 (std::string) 而无需 std::string 在内部分配/复制数据?

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

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

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

最佳答案

如果不复制数据,您实际上无法形成 std​​::string。 stringstream 可能会重复使用内存(尽管我认为标准没有说明它是否真的必须这样做),但它仍然无法避免复制。

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

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


更新(因为我仍然偶尔会看到对此答案的赞成票):

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

关于c++ - 从 char* 初始化 std::string 而不复制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5793965/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com