В чем смысл UTF-16?
Я никогда не понимал смысл кодировки UTF-16. Если вам нужно иметь возможность обрабатывать строки как произвольный доступ (т. е. кодовая точка совпадает с кодовой единицей), вам нужен UTF-32, поскольку UTF-16 по-прежнему является переменной длиной. Если вам это не нужно, то UTF-16 кажется колоссальной тратой пространства по сравнению с UTF-8. Каковы преимущества UTF-16 перед UTF-8 и UTF-32 и почему Windows и Java используют его в качестве своей собственной кодировки?
5 ответов:
, когда Windows NT была разработана в UTF-16 не существовало (НТ 3.51 родился в 1993 году, в то время как в UTF-16 родился в 1996 году с Юникод 2.0 стандарт); там было вместо ПСК-2, который, в то время, было достаточно, чтобы держать каждый персонаж доступен в Юникоде, так что 1 код = 1 код единица эквивалентности на самом деле было правдой - нет переменной длины логика, необходимая для строк.
Они перешли на UTF-16 позже, чтобы поддерживать весь набор символов Unicode; однако они не могли перейти на UTF-8 или UTF-32, потому что это нарушило бы двоичную совместимость в интерфейсе API (среди прочего).
Что касается Java, я не совсем уверен; поскольку он был выпущен в ~1995 году, я подозреваю, что UTF-16 уже был в воздухе (даже если он еще не был стандартизирован), но я думаю, что совместимость с операционными системами на основе NT, возможно, сыграла некоторую роль в их выборе (непрерывные преобразования UTF-8 UTF-16 для каждого вызова API Windows могут ввести некоторые замедление.)
Edit
Википедия объясняет, что даже для Java он пошел тем же путем: он первоначально поддерживал UCS-2, но перешел на UTF-16 в J2SE 5.0.
Итак, в общем случае, когда вы видите UTF-16, используемый в некоторых API / Framework, это связано с тем, что он начинался как UCS-2 (чтобы избежать осложнений в алгоритмах управления строками), но он перешел на UTF-16 для поддержки кодовых точек за пределами BMP, все еще сохраняя тот же кодовый блок размер.
ни один из ответов, указывающих на преимущество UTF-16 над UTF-8, не имеет никакого смысла, за исключением ответа на обратную совместимость.
Ну, есть два предостережения к моему комментарию.
Эрик заявляет: "UTF-16 покрывает всю BMP с помощью отдельных единиц - поэтому, если у вас нет необходимости в более редких символах за пределами BMP, UTF-16 фактически составляет 2 байта на символ."
нюанс 1)
Если вы можете быть уверены, что ваше приложение никогда не понадобится любой символ вне BMP, и что любой код библиотеки, который вы пишете для использования с ним, никогда не будет использоваться с любым приложением, которому когда-либо понадобится символ вне BMP, тогда вы можете использовать UTF-16 и написать код, который делает неявное предположение, что каждый символ будет ровно два байта в длину.
Это кажется чрезвычайно опасным (на самом деле, глупо).
Если ваш код предполагает, что все символы UTF-16 в длину два байта, и ваша программа взаимодействует с приложением или библиотекой, где есть один символ за пределами BMP, то ваш код будет сломан. Код, который проверяет или манипулирует UTF-16, должен быть написан для обработки случая символа UTF-16, требующего более 2 байт; поэтому я "отклоняю" это предостережение.
UTF-16 не проще кодировать, чем UTF-8 (код для обоих должен обрабатывать символы переменной длины).
нюанс 2)
UTF-16 может быть более вычислительно эффективным, под некоторые обстоятельства, если их правильно написать.
вот так: Предположим, что некоторые длинные строки редко изменяются, но часто исследуются (или лучше,никогда модифицированный после сборки-т. е. строковый конструктор, создающий неизменяемые строки). Флаг может быть установлен для каждой строки, указывая, содержит ли строка только символы "фиксированной длины" (т. е. не содержит символов, которые не являются точно двумя байтами в длину). Строки, для которых флаг истинен, можно проверить с помощью оптимизированный код, который принимает символы фиксированной длины (2 байта).
Как насчет космической эффективности?
UTF-16, очевидно, более эффективен для A) символов, для которых UTF-16 требует меньше байтов для кодирования, чем UTF-8.
UTF-8, очевидно, более эффективен для B) символов, для которых UTF-8 требует меньше байтов для кодирования, чем UTF-16.
за исключением очень "специализированного" текста, вполне вероятно, что count(B) намного превышает count (A).
UTF-16 охватывает весь BMP с одиночными блоками-поэтому, если у вас нет необходимости в более редких символах за пределами BMP, UTF-16 фактически составляет 2 байта на символ. UTF-32 занимает больше места, UTF-8 требует поддержки переменной длины.
UTF16 обычно используется в качестве прямого отображения на многобайтовые наборы символов, т. е. onyl исходные 0-0xFFFF назначенные символы.
Это дает вам лучшее из обоих миров, у вас есть фиксированный размер символов, но вы все еще можете печатать все символы, которые кто-либо может использовать (за исключением ортодоксальных клингонских религиозных сценариев)
UTF-16 позволяет представлять все базовые многоязычные плоскости (BMP) в виде отдельных кодовых единиц. Кодовые точки Unicode, не зависящим от U+ffff в представляются суррогатными парами.
интересно то, что Java и Windows (и другие системы, использующие UTF-16) все работают на уровне единицы кода, а не на уровне кодовой точки Unicode. Таким образом, строка, состоящая из одного символа U+1D122 (музыкальный символ F CLEF), кодируется в Java как "\ud824\udd22" и
"\ud824\udd22".length() == 2(не1). Так это своего рода хак, но оказывается, что символы не имеют переменной длины.преимущество UTF-16 над UTF-8 заключается в том, что можно было бы отказаться от слишком многого, если бы тот же хак использовался с UTF-8.
Comments