Существуют ли какие-либо практические ограничения на использование только std::string вместо массивов char и std ::vector / list вместо массивов в c ++?

StackOverflow https://stackoverflow.com/questions/801385

Вопрос

Я навязчиво использую векторы, списки, строки и wstrings в своем коде.Есть ли какие-либо уловки 22, которые должны заставить меня больше интересоваться использованием массивов время от времени, символов и wchars вместо них?

В принципе, если работать в среде, которая поддерживает стандартную библиотеку шаблонов, есть ли какой-либо случай, когда использование примитивных типов на самом деле лучше?

Это было полезно?

Решение

В 99% случаев и для 99% реализаций стандартных библиотек вы обнаружите, что std::vectors будет достаточно быстрым, а удобство и безопасность, которые вы получите от их использования, с лихвой перевесят любые небольшие затраты на производительность.

В тех очень редких случаях, когда вам действительно нужен простой код, вы можете обрабатывать вектор как массив в стиле C.:

vector <int> v( 100 );
int * p = &v[0];
p[3] = 42;

Стандарт C ++ гарантирует, что векторы распределяются последовательно, так что это гарантированно сработает.

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

Что касается списков, вам следует дважды, а возможно, и трижды, подумать, прежде чем использовать их вообще, будь то ваша собственная реализация или стандарт.Подавляющее большинство вычислительных задач лучше решается с помощью вектора / массива.Причина, по которой списки так часто появляются в литературе, во многом заключается в том, что они представляют собой удобную структуру данных, которую авторы учебников и учебных курсов могут использовать для объяснения указателей и динамического распределения за один раз.Я выступаю здесь как бывший автор учебных курсов.

Другие советы

Я бы придерживался классов STL (векторы, строки и т.д.).Они безопаснее, проще в использовании, производительнее, с меньшей вероятностью утечек памяти и, AFAIK, они выполняют некоторую дополнительную проверку границ во время выполнения, по крайней мере, во время отладки (Visual C ++).

Затем измерьте производительность.Если вы определили, что узкое место (ы) находится в классах STL, то перейдите к использованию строк и массивов в стиле C.

Исходя из моего опыта, вероятность возникновения узкого места при использовании вектора или строки очень мала.

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

Если вам не нужны ответы в режиме реального времени, придерживайтесь своего подхода.Они безопаснее, чем символы.

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

Я работал над проектами, где преобразование из std::string в const char * экономило заметную память (10 МБ).Я не думаю, что эти проекты можно назвать типичными.

О, использование STL сократит время компиляции, и в какой-то момент это может стать проблемой.Когда в результате вашего проекта компоновщику передается более гигабайта объектных файлов, возможно, вам захочется подумать, какая часть из них является раздуванием шаблона.

Я работал над несколькими проектами, где накладные расходы на память для строк стали проблематичными.

Стоит заранее подумать о том, как ваше приложение должно масштабироваться.Если вам нужно хранить неограниченное количество строк, используя const char*преобразование в глобально управляемую таблицу строк может сэкономить вам огромные объемы памяти.

Но, как правило, определенно используйте типы STL, если только нет очень веских причин поступить иначе.

Я полагаю, что метод выделения памяти по умолчанию - это буфер для векторов, а strings - это метод, который выделяет вдвое больший объем памяти каждый раз, когда используется текущая выделенная память.Это может быть расточительно.Конечно, вы можете предоставить пользовательский распределитель...

Другая вещь, которую следует учитывать, - это stack vs.куча.Массивы и строки статического размера могут находиться в стеке, или, по крайней мере, компилятор обрабатывает управление памятью за вас.Более новые компиляторы также будут обрабатывать массивы динамического размера для вас, если они предоставляют соответствующую функцию C99 / C ++ 0x.Векторы и строки всегда будут использовать кучу, и это может привести к проблемам с производительностью, если у вас действительно жесткие ограничения.

Как правило, используйте то, что уже есть, если только это не повредит вашему проекту из-за накладных расходов на скорость / память...вероятно, вы обнаружите, что для 99% материалов классы, предоставляемые STL, экономят ваше время и усилия, практически не влияя на производительность ваших приложений.(т.е."избегайте преждевременной оптимизации")

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top