Подтвердить что ты не робот

Есть ли причина предпочитать UTF-16 по сравнению с UTF-8?

Изучая атрибуты UTF-16 и UTF-8, я не могу найти причины предпочитать UTF-16.

Однако, проверяя Java и С#, он выглядит как строки и символы по умолчанию для UTF-16. Я думал, что это может быть по историческим причинам или, возможно, по соображениям производительности, но не может найти никакой информации.

Кто-нибудь знает, почему эти языки выбрали UTF-16? И есть ли веская причина для меня сделать это?

EDIT: Тем временем я также нашел этот ответ, который кажется актуальным и содержит некоторые интересные ссылки.

4b9b3361

Ответ 1

Восточноазиатским языкам обычно требуется меньше места хранения в UTF-16 (для 99% символов восточно-азиатского языка достаточно 2 байта), чем UTF-8 (обычно требуется 3 байта).

Конечно, для западных lanagues UTF-8 обычно меньше (1 байт вместо 2). Для смешанных файлов, таких как HTML (там, где много разметки), это большая часть muchness.

Обработка UTF-16 для приложений пользовательского режима немного проще, чем обработка UTF-8, поскольку суррогатные пары ведут себя почти так же, как ведут себя комбинации символов. Таким образом, UTF-16 обычно может обрабатываться как кодировка фиксированного размера.

Ответ 2

@Oak: это слишком долго для комментария...

Я не знаю о С# (и был бы очень удивлен: это означало бы, что они просто слишком много копировали Java), но для Java это просто: Java была задумана до выхода Unicode 3.1.

Следовательно, было меньше 65537 кодовых точек, поэтому каждый кодовой код Unicode все еще был установлен на 16-битный, и поэтому родилась Java char.

Конечно, это привело к сумасшедшим проблемам, которые по-прежнему влияют на Java-программистов (например, я) сегодня, где у вас есть метод charAt, который в некотором случае не возвращает ни символ Unicode, ни код Unicode и метод (добавленный в Java 5 ) codePointAt, который принимает аргумент, который не является числом кодовых точек, которые вы хотите пропустить! (вам нужно предоставить кодPointAt количество Java char, которое вы хотите пропустить, что делает его одним из наименее понятных методов в классе String).

Итак, yup, это определенно дико и запутывает большинство программистов на Java (большинство из них даже не знают об этих проблемах), и, конечно, это по исторической причине. По крайней мере, это было оправдание, которое возникло после того, как люди разозлились после этой проблемы: но это потому, что Unicode 3.1 еще не вышел.

:)

Ответ 3

Я предполагаю, что С#, использующий UTF-16, происходит из семейства операционных систем Windows NT, используя UTF-16 внутри.

Я предполагаю, что существуют две основные причины, по которым Windows NT использует UTF-16:

  • Для использования памяти: UTF-32 тратит много места для кодирования.
  • Для производительности: UTF-8 намного сложнее декодировать, чем UTF-16. В символах UTF-16 либо базовый многоязычный символ (2 байта) или суррогат Пара (4 байта). Символы UTF-8 может быть где угодно между 1 и 4 байтов.

Вопреки тому, что ответили другие люди, вы не можете рассматривать UTF-16 как UCS-2. Если вы хотите правильно перебрать действительные символы в строке, вам нужно использовать дружественные к юникоду итерации функции. Например, в С# вам нужно использовать StringInfo.GetTextElementEnumerator().

Для получения дополнительной информации эту страницу в вики стоит прочитать: http://en.wikipedia.org/wiki/Comparison_of_Unicode_encodings

Ответ 4

Это зависит от ожидаемых наборов символов. Если вы ожидаете интенсивного использования кодовых точек Unicode за пределами 7-разрядного диапазона ASCII, вы можете обнаружить, что UTF-16 будет более компактным, чем UTF-8, поскольку некоторые последовательности UTF-8 имеют длину более двух байтов.

Кроме того, по соображениям эффективности Java и С# не учитывают суррогатные пары при индексировании строк. Это полностью разрушится при использовании кодовых точек, которые представлены последовательностями UTF-8, которые занимают нечетное количество байтов.

Ответ 5

UTF-16 может быть более эффективным для представления символов на некоторых языках, таких как китайский, японский и корейский, где символы наиболее могут быть представлены в одном 16-битном слове. Некоторым редко используемым символам могут потребоваться два 16-битных слова. UTF-8, как правило, гораздо эффективнее для представления символов из западноевропейских наборов символов. UTF-8 и ASCII эквивалентны по диапазону ASCII (0-127), но менее эффективны с азиатскими языками, для чего требуется три или четыре байта для представления символов, которые может быть представлено двумя байтами в UTF-16.

UTF-16 имеет преимущество как формат памяти для Java/С# в том, что каждый символ в базовой многоязычной плоскости может быть представлен в 16 бит (см. ответ Джо) и некоторые из недостатков UTF-16 (например, запутанный код, основанный на\0-терминаторах) менее актуальны.

Ответ 6

Для многих (наиболее?) приложений вы будете иметь дело только с символами в Basic Multilingual Plane, поэтому можете обрабатывать UTF-16 как кодирование с фиксированной длиной.

Итак, вы избегаете всей сложности кодировок переменной длины, например UTF-8.