Почему UTF-32 вместо UTF-16, если у нас есть суррогатные пары?

Если я правильно понимаю, UTF-32 может обрабатывать каждый символ во Вселенной. Таким образом, UTF-16, используя суррогатные пары. Итак, есть ли веская причина использовать UTF-32 вместо UTF-16?

Ответы

Ответ 1

В UTF-32 символ Юникода всегда будет представлен 4 байтами, поэтому код синтаксического анализа будет легче писать, чем код строки UTF-16, потому что в UTF-16 символ представлен переменным количеством байтов. С другой стороны, чат-менеджер UTF-32 будет всегда требовать 4 байта, которые могут быть расточительными, если вы работаете в основном с английскими символами. Таким образом, его выбор дизайна зависит от ваших требований, следует ли использовать UTF-16 или UTF-32.

Ответ 2

Кто-то может предпочесть работать с UTF-32 вместо UTF-16, потому что обращение с суррогатными парами почти всегда обрабатывает "особые случаи", и иметь дело с этими особыми случаями означает, что у вас есть области, где ошибки могут появляться в потому что вы имеете дело с ними неправильно (или, скорее всего, просто забываете иметь с ними дело вообще).

Если увеличение использования UTF-32 в памяти не является проблемой, уменьшенная сложность может быть достаточной для выбора.

Ответ 3

Вот хорошая документация из Консорциума Unicode.

Сравнение преимуществ UTF-32, UTF-16 и UTF-8

Copyright © 1991-2009 Unicode, Inc. Стандарт Unicode, версия 5.2

На первый взгляд, UTF-32, по-видимому, является очевидным выбором форм кодирования Unicode для внутреннего кода обработки, поскольку это форма кодирования с фиксированной шириной. Он может быть соответствующим образом связан с C и С++ wchar_t, что означает, что такие языки программирования могут предлагать встроенную поддержку и готовые API-интерфейсы строк, которые могут использовать программисты. Тем не менее, UTF-16 имеет много преимуществ, которые могут привести к тому, что разработчики вместо этого выбирают его как внутренний код обработки. В то время как для всех трех форматов кодирования требуется не более 4 байтов (или 32 бита) данных, на практике UTF-32 почти во всех случаях для реальных наборов данных занимает в два раза больше памяти, которую требует UTF-16. Таким образом, общая стратегия состоит в том, чтобы внутреннее хранилище строк использовало UTF-16 или UTF-8, но для использования UTF-32 при манипулировании отдельными символами.

UTF-32 в сравнении с UTF-16.В среднем более 99 процентов всех данных UTF-16 выражаются с использованием единичных кодовых единиц. Это включает почти все типичные символы, которые программное обеспечение должно обрабатывать со специальными операциями над текстом, например, символы управления форматом. Как следствие, большинству операций текстового сканирования вообще не нужно распаковывать суррогатные пары UTF-16, но они могут безопасно относиться к ним как к непрозрачной части символьной строки. Для многих операций UTF-16 так же прост в обращении, как UTF-32, а производительность UTF-16 в качестве кода обработки, как правило, неплохая. UTF-16 является внутренним кодом обработки для большинства реализаций, поддерживающих Unicode. В отличие от платформ Unix, UTF-16 обеспечивает правильное сочетание компактных размеров с возможностью обработки случайного символа вне BMP. UTF-32 имеет некоторое преимущество, когда речь идет о простоте разработки и обслуживания программного кодирования. Поскольку обработка символов является фиксированной шириной, обработка UTF-32 не требует поддержки ветвей в программном обеспечении для тестирования и обработки элементов кода двойного кода, требуемых для дополнительных символов UTF-16. И наоборот, 32-разрядные индексы в большие таблицы не особенно эффективны с точки зрения памяти. Чтобы избежать больших ограничений памяти таких индексов, таблицы Unicode часто обрабатываются как многоступенчатые таблицы (см. "Многоэтапные таблицы" в разделе 5.1 "Транскодирование в другие стандарты" ). В таких случаях значения 32-разрядной кодовой точки разрезаются на меньшие диапазоны, чтобы обеспечить сегментированный доступ к таблицам. Это справедливо даже в типичных реализациях UTF-32. Производительность UTF-32 в качестве кода обработки на самом деле может быть хуже, чем производительность UTF-16 для одних и тех же данных, поскольку дополнительные служебные данные памяти означают, что пределы кэша будут превышены чаще, а пейджинг памяти будет происходить чаще. Для систем с процессорами, которые налагают штрафы за 16-битный согласованный доступ, но имеют очень большие воспоминания, этот эффект может быть менее заметным. В любом случае кодовые точки Unicode не обязательно соответствуют ожиданиям пользователей для "символов". Например, следующее не представлено одной кодовой точкой: комбинационная последовательность символов, такая как; последовательная последовательность jamo для корейцев; или деванагари-конъюнктом "кша". Поскольку некоторая обработка текста в Юникоде должна знать и обрабатывать такие последовательности символов, как текстовые элементы, преимущество формы кодирования с фиксированной шириной UTF-32 несколько компенсируется характером обработки текстовых элементов с измененной шириной. См. Технический стандарт Unicode № 18 "Единичные регулярные выражения" для примера, в котором обычно реализуемые процессы обрабатывают текстовые элементы переменной ширины из-за ожиданий пользователя от идентичности "символа". UTF-8. UTF-8 достаточно компактен по количеству используемых байтов. Это действительно только при значительном невыгодном размере, когда используется для восточно-азиатских реализаций, таких как китайский, японский и корейский, которые используют ханьские идеограммы или хангыльские слоги, требующие трехбайтовых кодовых блоков в UTF-8. UTF-8 также значительно менее эффективен с точки зрения обработки, чем другие формы кодирования. Бинарная сортировка. Бинарный тип строк UTF-8 дает тот же порядок, что и двоичный тип кодов Unicode. Это, очевидно, тот же порядок, что и для двоичного типа строк UTF-32.

Общая структура

Все три формы кодирования дают одинаковые результаты для бинарных сравнений строк или сортировки строк при работе только с символами BMP (в диапазоне U + 0000..U + FFFF). Однако при работе с дополнительными символами (в диапазоне U + 10000..U + 10FFFF) двоичный порядок UTF-16 не соответствует порядковому порядку в кодировке Unicode. Это может привести к осложнениям при попытке взаимодействия с бинарными отсортированными списками, например, между системами UTF-16 и системами UTF-8 или UTF-32. Однако для данных, которые сортируются в соответствии с разрешениями конкретного языка или локали, а не с использованием двоичного порядка, данные будут упорядочены одинаково независимо от формы кодирования.

Ответ 4

Короткий ответ: нет.

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

Меньше саркастический ответ: когда вам больше нужна скорость индексирования, чем использование пространства или как промежуточный формат какого-то типа, или на машинах, где проблемы с выравниванием важнее проблем с кешем или...

Ответ 5

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

С UTF-32 вы знаете, что каждый символ имеет 4 байта. С UTF-16 вы не знаете, какой длины будет иметь какой-либо конкретный символ.

Например, у вас есть функция, которая возвращает nth char строки:

char getChar(int index, String s );

Если вы кодируете язык, на котором есть прямой доступ к памяти, скажем C, то в UTF-32 эта функция может быть такой же простой, как некоторый арифметический указатель (s+(4*index)), который будет представлять собой некоторые суммы O (1).

Если вы используете UTF-16, вам придется ходить по строке, расшифровывать по мере того, как вы шли, что было бы O (n).

Ответ 6

UTF-8 также может представлять любой символ Юникода!

Если ваш текст в основном по-английски, вы можете сэкономить много места, используя utf-8, но индексирующие символы не являются O (1), потому что некоторые символы занимают не более одного байта.

Если пространство не так важно для вашей ситуации, как скорость, utf-32 подойдет вам лучше, потому что индексирование - это O (1)

UTF-16 может быть лучше, чем utf-8 для текста, отличного от английского, потому что в utf-8 у вас есть ситуация, когда некоторые символы занимают 3 байта, где, как и в utf16, они занимают только два байта.

Ответ 7

В общем, вы просто используете строковый тип данных/кодировку базовой платформы, которая часто (Windows, Java, Cocoa...) UTF-16, а иногда и UTF-8 или UTF-32. Это в основном по историческим причинам; между тремя кодировками Юникода мало различий: все три четко определены, быстрые и надежные, и все они могут кодировать каждую последовательность кодов Юникода. Уникальной особенностью UTF-32 является кодирование с фиксированной шириной (что означает, что каждая точка кода представлена ​​ровно одним блоком кода) практически не используется: на уровне управления памятью необходимо знать количество и ширину кода юниты, а пользователи заинтересованы в абстрактных символах и графемах. Как уже упоминалось в стандарте Unicode, приложения Unicode должны иметь дело с комбинированными символами, лигатурами и так далее, и обработка суррогатных пар, несмотря на концептуальную разницу, может быть выполнена в рамках тех же технических рамок.

Если бы я должен был изобретать мир, я бы, вероятно, пошел на UTF-32, потому что это просто наименее сложная кодировка, но, поскольку это стоит, различия слишком малы, чтобы иметь практическое значение.