代码之家  ›  专栏  ›  技术社区  ›  Akusete

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

  •  42
  • Akusete  · 技术社区  · 17 年前

    我需要处理大量(许多GB)的数据,例如:

    1. 修剪绳子

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

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

    是否有一种方法将C字符串(char)转换成STL C++字符串(STD::string),而不需要STD::string来内部分配/复制数据?

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

    谢谢你的回答,为了清楚起见,我想修改后的问题是:

    6 回复  |  直到 17 年前
        1
  •  25
  •   puetzk    9 年前

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

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

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


    使现代化

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

        2
  •  18
  •   James Eichele Bernard Igiri    13 年前

    string::reserve(size_t)

    看见 this link 有关 reserve

        3
  •  7
  •   Loki Astari    14 年前

    为了帮助处理非常大的字符串,SGI的STL中有类Rope。
    非标准,但可能有用。

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


    注意开发人员的笑话。绳子是一根大绳子。(哈哈):-)

        4
  •  6
  •   Daniel Earwicker    17 年前

    std::string的只读处理实际上并不需要std::string功能的非常复杂的子集。您是否有可能对执行std::strings所有处理的代码执行搜索/替换,以便它采用其他类型?从空白类开始:

    类轻量级_字符串{};

        5
  •  2
  •   David Norman    17 年前

    将char*分配到std::string中必须始终至少复制数据。内存管理是使用std::string的主要原因之一,因此您将无法重写它。

        6
  •  0
  •   Alan    17 年前