Инициализация std::string из char* без копирования
У меня возникла ситуация, в которой необходимо обрабатывать большие объемы данных (многие гигабайты) следующим образом:
- Создание большой строки путём подключения множества меньших (C char*) строк.
- Обрезка строки.
- Преобразование строки в неизменяемую C++ std::string для дальнейшей обработки (только для чтения).
- Повторение процесса.
Данные в каждой итерации независимы.
Мой вопрос заключается в том, как минимизировать (а если возможно, полностью устранить) использование памяти, выделяемой в куче, так как это на данном этапе является моей самой большой проблемой с производительностью.
Существует ли способ конвертировать строку C (char*) в STL C++ строку (stdstring) без необходимости внутреннего выделения или копирования данных в stdstring?
В качестве альтернативы, могу ли я использовать stringstreams или что-то подобное для повторного использования большого буфера?
Редактирование: Спасибо за ответы. Для ясности, я думаю, что измененный вопрос звучал бы так:
Как эффективно создать (путём множественного соединения) STL C++ строку. И если выполнять это действие в цикле, где каждая итерация полностью независима, как я могу повторно использовать это выделенное пространство?
4 ответ(ов)
Чтобы работать с действительно большими строками, SGI предлагает класс Rope в своей STL.
Хотя это нестандартное решение, оно может оказаться полезным.
http://www.sgi.com/tech/stl/Rope.html
Судя по всему, rope будет включен в следующую версию стандарта 😃
Обратите внимание на шутку для разработчиков: rope (веревка) — это большая строка. (Ха-ха) 😃
Это ответ в стиле бокового мышления, который не совсем напрямую отвечает на вопрос, но предлагает обойти его стороной. Возможно, это окажется полезным, а может и нет...
Чтение stdstring в режиме "только для чтения" на самом деле не требует слишком сложного набора его функций. Существует ли возможность изменить код, который выполняет всю обработку stdstring, так, чтобы вместо него использовался какой-то другой тип? Начните с создания пустого класса:
class lightweight_string { };
Затем замените все ссылки на std::string на lightweight_string. После этого выполните компиляцию, чтобы точно выяснить, какие операции требуются для того, чтобы lightweight_string мог выступать в качестве замены. После этого вы сможете реализовать функциональность так, как вам нужно.
В каждой итерации достаточно ли независимы объекты, чтобы вы могли использовать одну и ту же std::string
? Можно надеяться, что ваша реализация std::string
достаточно умна, чтобы повторно использовать память в случае, если вы присваиваете ей const char *
, ранее использованный для чего-то другого.
Тем не менее, присвоение char *
объекту std::string
всегда как минимум приведет к копированию данных. Управление памятью — одна из основных причин использования std::string
, и вы не сможете это переопределить.
В данном случае, возможно, будет лучше обрабатывать указатель char*
напрямую, вместо того чтобы присваивать его объекту std::string
. Это может быть более эффективно с точки зрения производительности, так как вам не нужно будет создавать лишний объект std::string
, который требует выделения памяти и может привести к дополнительным накладным расходам на копирование данных.
Однако, стоит учитывать, что работа с сырыми указателями требует большей аккуратности — вам необходимо следить за управлением памятью и избегать потенциальных утечек или ошибок. Если ваш код предполагает манипуляцию с текстовыми данными и вам важна безопасность, то использование std::string
может быть более предпочтительным вариантом благодаря автоматическому управлению памятью и удобству работы с строками.
Таким образом, выбор между использованием char*
и std::string
должен основываться на ваших конкретных требованиях к производительности и безопасности.
Можно ли получить доступ к памяти локальной переменной вне её области видимости?
Почему моя программа работает медленно при обходе ровно 8192 элементов?
Как преобразовать std::string в int?
Проверка содержимого строки в строке на C++
Копирование не нуль-терминированного массива unsigned char в std::string