2016-01-06 5 views
7

Прежде чем начать, мне нужно указать, что мое приложение использует множество строк, которые в среднем довольно малы и которые не меняются после создания.Могу ли я заставить std :: string использовать меньше памяти?

В Visual Studio 2010 я заметил, что емкость std :: string не менее 30. Даже если я пишу std::string str = "test";, емкость str равна 30. Функция str.shrink_to_fit() ничего не делает, хотя функция с тем же name существует для std :: vector и работает как ожидалось, а именно, уменьшая емкость, так что емкость == size.

  1. Почему std::string::shrink_to_fit() не работает в ожидании?
  2. Как я могу гарантировать, что строка выделяет наименьший объем памяти?
+0

http://www.stackoverflow.com/questions/2916358/immutable-strings-vs-stdstring – JimmyB

+0

Вы можете использовать пользовательский распределитель для 'std :: basic_string'. Однако при этом будет создан тип строки, который несовместим с 'std :: string'. – kfx

+0

Это звучит как оптимизация небольшого буфера с помощью более крупного буфера. Если это небольшая оптимизация буфера, вы не можете уменьшить ее. –

ответ

8
  1. Ваш std::string реализация, скорее всего, использует некоторую форму short string optimization в результате фиксированного размера для небольших строк и не влияет на shrink_to_fit. Обратите внимание, что shrink_to_fit не имеет обязательной силы для реализации, поэтому это фактически соответствует.
  2. Вы можете использовать vector<char>, чтобы получить более точное управление памятью, но потеряете некоторые дополнительные функции std::string. Вы также можете написать свою собственную упаковку string, которая внутренне использует vector.
1

Одна из причин, что std::string::shrink_to_fit() ничего не делает то, что это не требуется по стандарту

Примечания:shrink_to_fit является необязывающий запрос для снижения capacity() к size(). [Примечание. Запрос не является обязательным, чтобы разрешить широту для конкретных реализаций. -end примечание]

Если вы хотите, чтобы убедиться, что строка сжимается, то вы можете использовать swap() трюк как

std::string(string_to_shrink).swap(string_to_shrink) 

Еще одна причина, это не может работать в том, что реализатор std::string разрешается осуществлять short string optimization, чтобы вы могли всегда иметь минимальный размер 30 для вашей реализации.

+0

Трюк с заменой, по сути, означает, что «shrink_to_fit» должен был заменить. Я думаю, что проблема здесь - это SSO. – pmr

1

То, что вы наблюдаете, является результатом SSO (оптимизация коротких строк), как указано другими.

Что вы можете сделать об этом зависит от характера использования:

  • Если строки являются частями одной большой строки, что характерно для синтаксического анализа, вы можете использовать классы как std::experimental::string_view, GSL string_span, Google, StringPiece, LLVM's StringRef и т. Д., Которые сами не хранят данные, а относятся только к части какой-либо другой строки, обеспечивая при этом интерфейс, аналогичный std::string.

  • Если имеется несколько копий одних и тех же строк (особенно длинных), может иметь смысл использовать строки CoW (copy-on-write), где копии совместно используют один и тот же буфер с использованием механизма счетчика ссылок до тех пор, пока не будут изменены. (Но быть в курсе недостатков)

  • Если строки очень короткие (всего несколько символов) может иметь смысл, чтобы написать свой собственный специализированный класс, то в соответствии с Handling short codes Анджея

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

Обновление: после перечитывания введения в вопрос, я думаю, что третий подход является лучшим для вас.

Смежные вопросы