Около десяти лет назад в одном из проектов мы обнаружили, что динамическое распределение std::vector
вызывало серьезную потерю производительности. В этом случае было выделено много небольших векторов, поэтому быстрым решением было написать векторный класс, обернутый вокруг предварительно выделенного массива char
на основе стека, используемого в качестве необработанного хранилища для его емкости. Результат был static_vector<typename T, std::size_t Max>
. Такую вещь достаточно легко написать, если вы знаете некоторые основы, и вы можете найти немало таких чудовищ в сети < / а>. Фактически, у есть одно повышение, тоже сейчас.
Сейчас, работая над встроенной платформой, нам понадобится static_basic_string
. Это будет строка, которая предварительно выделяет фиксированный максимальный объем памяти в стеке и использует его в качестве своей емкости.
Сначала я подумал, что это должно быть довольно просто (в конце концов, это могло быть основано на существующем static_vector
), но, снова взглянув на интерфейс std::basic_string
, я уже не в этом уверен. Это намного сложнее, чем интерфейс std::vector
. В частности, реализация семейства find()
функций, поставляемых с std::basic_string
, - это больше, чем просто утомительная задача.
Это заставило меня снова задуматься. В конце концов, это то, для чего были созданы распределители: заменить распределение, основанное на new
и delete
, другими средствами. Однако сказать, что интерфейс распределителя является громоздким, было бы преуменьшением. Есть несколько статей, объясняющих это, но есть причина, по которой я видел так очень мало самодельных распределителей памяти за последние 15 лет.
Вот мой вопрос:
Если бы вам пришлось реализовать basic_string
двойника, как бы вы это сделали?
- Напишите свой
static_basic_string
? - Написать распределитель для перехода к
std::basic_string
? - Сделать то, о чем я не подумал?
- Использовать что-то из Boost, о котором я не знаю?
Как всегда, для нас существует довольно существенное ограничение: будучи на встроенной платформе, мы привязаны к GCC 4.1.2, поэтому можем использовать только C ++ 03, TR1 и boost 1.52.
std::basic_string
), и меня больше интересует, как его реализовать. Да, это нечетко, но я считаю, что вопрос здесь больше, чем там. ICBWT. - person sbi   schedule 14.10.2014std::basic_string
экземпляра, независимо от того, как его содержимое изменится позже? - person Angew is no longer proud of SO   schedule 14.10.2014using
). - person Angew is no longer proud of SO   schedule 14.10.2014std::string
с большой начальной емкостью и некоторым ограничением на сайте вызова на максимальный размер строки ?! Стоимость одного динамического распределения действительно хуже, чем этот уровень сложности и несомненно хрупкий код, который следует за ним? Я предполагаю, что если вы создаете метрический фрагмент этих вещей, но вместо этого пытаетесь использовать их повторно? Дополнительная информация о варианте использования и исходных проблемах, с которыми вы столкнулись, может помочь нам предоставить каноническое решение, которое не ограничивается NIHing. - person Lightness Races in Orbit   schedule 14.10.2014struct
с большим количеством мелких строковых членов - имея их почти непрерывно в памяти - обычно на одной (ах) странице (ах) кеша - звучит очень выгодно по сравнению с хранением каждого указателями, которые - даже если из один и тот же настраиваемый пул - может быть непрактично, чтобы избежать несмежного распределения без других нежелательных накладных расходов на координацию. - person Tony Delroy   schedule 14.10.2014