Профилирование моего приложения показывает, что оно тратит почти 5% процессорного времени на распределение строк. Во многих местах я делаю объекты C ++ std :: string из 64-мегабайтного буфера символов. Дело в том, что буфер не изменяется во время работы программы. Мой анализ std::string(const char *buf,size_t buflen)
вызывает то, что строка копируется, потому что буфер может измениться после создания строки. Это не проблема здесь. Есть ли способ обойти эту проблему?
РЕДАКТИРОВАТЬ: я работаю с двоичными данными, поэтому я не могу просто обойти char *s
, Кроме того, тогда у меня были бы существенные издержки от постоянного сканирования на NULL, которое std::string
избегает.
Двоичные данные? Прекратите использовать 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 делает ненужные копии буфера.
Если строка не изменится и если ее время жизни будет гарантированно длиннее, чем вы собираетесь использовать строку, то не используйте std::string
,
Вместо этого рассмотрим простую оболочку строки C, как string_ref<T>
.
Нет портативного решения. Если вы сообщите нам, какой набор инструментов вы используете, кто-то может знать хитрость, характерную для вашей реализации библиотеки. Но по большей части, std::string
Деструктор (и оператор присваивания) собирается освободить содержимое строки, и вы не можете освободить строковый литерал. (Не исключено, что могут быть исключения из этого, и на самом деле небольшая строковая оптимизация является распространенным случаем, который пропускает освобождение, но это детали реализации.)
Лучший подход — не использовать std::string
когда вам не нужно / нужно динамическое распределение. const char*
все еще прекрасно работает в современном C ++.
Кажется что используя const char *
вместо std::string
это лучший способ для вас. Но вы должны также рассмотреть, как вы используете строки. Возможно, что происходит неявное преобразование из указателей символов в std::string
объекты. Это может произойти, например, во время вызовов функций.