производительность — Могу ли я сделать нулевое копирование std :: string в C ++ из константного массива char *?

Профилирование моего приложения показывает, что оно тратит почти 5% процессорного времени на распределение строк. Во многих местах я делаю объекты C ++ std :: string из 64-мегабайтного буфера символов. Дело в том, что буфер не изменяется во время работы программы. Мой анализ std::string(const char *buf,size_t buflen) вызывает то, что строка копируется, потому что буфер может измениться после создания строки. Это не проблема здесь. Есть ли способ обойти эту проблему?

РЕДАКТИРОВАТЬ: я работаю с двоичными данными, поэтому я не могу просто обойти char *s, Кроме того, тогда у меня были бы существенные издержки от постоянного сканирования на NULL, которое std::string избегает.

4

Решение

Двоичные данные? Прекратите использовать std :: string и используйте std::vector<char>, Но это не решит проблему копирования. Из вашего описания, если этот огромный 64 МБ буфер никогда не изменится, вам действительно не следует использовать std :: string или std::vector<char>Либо одна не очень хорошая идея. Вы действительно должны обойти указатель const char * (const uint8_t * будет более описательным для двоичных данных, но под прикрытием это то же самое, пренебрегая проблемами со знаками). Обведите указатель и его размер size_t или передайте указатель с другим указателем ‘end’. Если вам не нравится передавать отдельные дискретные переменные (указатель и длину буфера), создайте структуру для описания буфера & пусть все используют их вместо:

struct binbuf_desc {
uint8_t* addr;
size_t len;
binbuf_desc(addr,len) : addr(addr), len(len) {}
}

Вы всегда можете обратиться к своему буферу 64 МБ (или любому другому буферу любого размера), используя binbuf_desc объекты. Обратите внимание, что объектам binbuf_desc не принадлежит буфер (или его копия), они просто являются его дескриптором, поэтому вы можете просто передавать его везде, не беспокоясь о том, что binbuf_desc делает ненужные копии буфера.

3

Другие решения

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

Вместо этого рассмотрим простую оболочку строки C, как string_ref<T>.

7

Нет портативного решения. Если вы сообщите нам, какой набор инструментов вы используете, кто-то может знать хитрость, характерную для вашей реализации библиотеки. Но по большей части, std::string Деструктор (и оператор присваивания) собирается освободить содержимое строки, и вы не можете освободить строковый литерал. (Не исключено, что могут быть исключения из этого, и на самом деле небольшая строковая оптимизация является распространенным случаем, который пропускает освобождение, но это детали реализации.)

Лучший подход — не использовать std::string когда вам не нужно / нужно динамическое распределение. const char* все еще прекрасно работает в современном C ++.

3

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

0
По вопросам рекламы [email protected]