0

Инициализация std::string из char* без копирования

10

У меня возникла ситуация, в которой необходимо обрабатывать большие объемы данных (многие гигабайты) следующим образом:

  1. Создание большой строки путём подключения множества меньших (C char*) строк.
  2. Обрезка строки.
  3. Преобразование строки в неизменяемую C++ std::string для дальнейшей обработки (только для чтения).
  4. Повторение процесса.

Данные в каждой итерации независимы.

Мой вопрос заключается в том, как минимизировать (а если возможно, полностью устранить) использование памяти, выделяемой в куче, так как это на данном этапе является моей самой большой проблемой с производительностью.

Существует ли способ конвертировать строку C (char*) в STL C++ строку (stdstring) без необходимости внутреннего выделения или копирования данных в stdstring?

В качестве альтернативы, могу ли я использовать stringstreams или что-то подобное для повторного использования большого буфера?

Редактирование: Спасибо за ответы. Для ясности, я думаю, что измененный вопрос звучал бы так:

Как эффективно создать (путём множественного соединения) STL C++ строку. И если выполнять это действие в цикле, где каждая итерация полностью независима, как я могу повторно использовать это выделенное пространство?

4 ответ(ов)

0

Чтобы работать с действительно большими строками, SGI предлагает класс Rope в своей STL.

Хотя это нестандартное решение, оно может оказаться полезным.

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

Судя по всему, rope будет включен в следующую версию стандарта 😃

Обратите внимание на шутку для разработчиков: rope (веревка) — это большая строка. (Ха-ха) 😃

0

Это ответ в стиле бокового мышления, который не совсем напрямую отвечает на вопрос, но предлагает обойти его стороной. Возможно, это окажется полезным, а может и нет...

Чтение stdstring в режиме "только для чтения" на самом деле не требует слишком сложного набора его функций. Существует ли возможность изменить код, который выполняет всю обработку stdstring, так, чтобы вместо него использовался какой-то другой тип? Начните с создания пустого класса:

class lightweight_string { };

Затем замените все ссылки на std::string на lightweight_string. После этого выполните компиляцию, чтобы точно выяснить, какие операции требуются для того, чтобы lightweight_string мог выступать в качестве замены. После этого вы сможете реализовать функциональность так, как вам нужно.

0

В каждой итерации достаточно ли независимы объекты, чтобы вы могли использовать одну и ту же std::string? Можно надеяться, что ваша реализация std::string достаточно умна, чтобы повторно использовать память в случае, если вы присваиваете ей const char *, ранее использованный для чего-то другого.

Тем не менее, присвоение char * объекту std::string всегда как минимум приведет к копированию данных. Управление памятью — одна из основных причин использования std::string, и вы не сможете это переопределить.

0

В данном случае, возможно, будет лучше обрабатывать указатель char* напрямую, вместо того чтобы присваивать его объекту std::string. Это может быть более эффективно с точки зрения производительности, так как вам не нужно будет создавать лишний объект std::string, который требует выделения памяти и может привести к дополнительным накладным расходам на копирование данных.

Однако, стоит учитывать, что работа с сырыми указателями требует большей аккуратности — вам необходимо следить за управлением памятью и избегать потенциальных утечек или ошибок. Если ваш код предполагает манипуляцию с текстовыми данными и вам важна безопасность, то использование std::string может быть более предпочтительным вариантом благодаря автоматическому управлению памятью и удобству работы с строками.

Таким образом, выбор между использованием char* и std::string должен основываться на ваших конкретных требованиях к производительности и безопасности.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь