Использование недопустимого октета UTF-8 в качестве разделителя в std :: string - PullRequest
1 голос
/ 30 мая 2019

Надеюсь, улучшенная и более сфокусированная версия моего вопроса:

По причинам, которые было бы неверным для объяснения (см. Ниже), я должен хранить несколько строк в кодировке UTF-8 водна строка(Строка означает C ++ std::string здесь)

Мой подход заключается в объединении строк с одним из недопустимых октетов UTF-8 (0xC0, 0xC1, 0xF5-0xFF) в качестве разделителя, так как эти октеты никогда не появятсяв допустимой последовательности UTF-8.(Так как 0x00 является действительным октетом UTF-8, я думаю, что он не подходит для моего предполагаемого неправильного использования.)

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

..

В своем первоначальном вопросе я попытался представить больше контекста, но это привело к нескольким вопросам о проблемах производительности и предполагаемой торговле.-off.Но мой вопрос не об этих компромиссах, а о том, насколько технически осуществим и обоснован мой подход.

1 Ответ

1 голос
/ 31 мая 2019

Как уже упоминалось, использование любого байта, который работает в вашей ситуации, будет прекрасно работать в std::string.Хотя если в ваших строках иначе не используется '\0', возможно, будет лучше использовать такой, а не недопустимый байт UTF-8.

Если ваша реализация удовлетворительна с точки зрения скорости, тогда я думаю, что это,В противном случае вы можете посмотреть, как управляются базы данных.В этом случае вы бы использовали буферы фиксированного размера.Большим преимуществом является то, что вы не разбиваете память на множество маленьких кусочков и не запускаете проблемы с выделением памяти позже.Кроме того, по скорости вы бы распределили эти блоки один раз и использовали бы их много раз.Функции malloc() и free() дороги, особенно если у вас есть тонна объектов (операторы new и delete вызывают эти функции.)

Теперь, чтобы сохранить еще больше памяти, так как она звучитэто главная цель, и, если возможно, в вашей ситуации, вы можете подумать о сжатии ваших строк с помощью zlib.Я бы использовал самый быстрый режим сжатия и посмотрел, меньше ли результирующий буфер, если да, используйте его.В противном случае сохраните несжатую строку.Для этого необходимо сохранить размер (4 байта) на строку.Вы можете установить размер равным 0, когда буфер не сжат.

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

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

...