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

Я использую векторы, списки, строки и строки в своем коде. Существуют ли какие-то уловки 22, которые должны время от времени меня больше интересовать, используя вместо этого массивы, символы и символы?

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

Ответы [ 7 ]

3 голосов
/ 29 апреля 2009

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

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

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

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

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

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

3 голосов
/ 29 апреля 2009

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

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

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

2 голосов
/ 29 апреля 2009

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

0 голосов
/ 29 апреля 2009

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

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

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

0 голосов
/ 29 апреля 2009

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

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

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

0 голосов
/ 29 апреля 2009

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

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

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

0 голосов
/ 29 апреля 2009

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

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