Пётр - Тексты на русском [entries|archive|friends|userinfo]
Пётр

[ website | My Website ]
[ userinfo | ljr userinfo ]
[ archive | journal archive ]

Тексты на русском [Aug. 11th, 2009|05:45 pm]
Previous Entry Add to Memories Tell A Friend Next Entry
Прикинул тут, сколько занимает один и тот же случайный текст (Стругацкие, "Град обречённый", с lib.ru сохранённый в текстовый файл).
Не поручусь за отличное качество перекодирования, но, вроде, текст тот же (конец строки по-разному обозначается).
Сравнил кодировки CP-1251, CP-866 и KOI-8, а также UTF-7, UTF-8, UTF-16 и UTF-32.

Основные отличия кодировок:
1. Первые три служат для хранения текста кириллицей или латиницей, последние четыре — всего многообразия символов Юникода.
2. Первые три хранят один символ в одном байте (ну, перевод строки может быть исключением), последняя — в четырёх, а UTF-7, UTF-8 и UTF-16 — в переменном количестве байтов.

Основной интерес вызывает то, насколько обременительно использовать UTF-32, единственную кодировку, не мучающую программиста этим переменным количеством байтов на символ, но позволяющую хранить текст, записанный в разных алфавитах (включая древнефиникийский и глаголицу) или некоторых иероглифических системах (не включая древнеегипетскую на данный момент).

Я просто "сжал" текст в каждой кодировке четырьмя способами: gzip (версия 1.2.4) с уровнем сжатия 1, 6 (по умолчанию) и 9 (gzip поддерживается стандартами интернета), а также 7zip (версия 4.62) с уровнем сжатия Ultra в режиме LZMA (просто как пример эффективно сжимающего архиватора).

Исходный текст был в CP-1251, занимал 799584 байта1. Привожу относительные значения.

Gzip/1Gzip/6Gzip/97Zip
CP-12511.000.490.420.420.35
CP-8661.000.500.420.420.36
KOI-80.980.480.420.420.35
UTF-722.340.840.590.560.41
UTF-81.690.690.500.490.38
UTF-161.960.690.520.500.36
UTF-323.931.050.670.580.37



Пример грубых выводов


Таким образом, если для долговременного хранения использовать сильное сжатие, то похоже на то, что UTF-32 достаточно удобен (в худшую сторону выбивается только UTF-7): по объёму не хуже, чем остальные форматы Юникода и однобайтовые кодировки.
При использовании самого быстрого метода сжатия разница в объёме текста в однобайтовой и четырёхбайтовой кодировках изменилась с отличия в четыре раза до отличия в два раза.
При использовании более мощных методов сжатия UTF-32 превосходит в объёме остальные кодировки Юникода не более, чем примерно на треть.



1
(Список длин, на всякий случай. Ну, если вдруг ошибся в таблице, например. Упорядочены по размеру.
282263 =KOI8.7z
283602 =CP1251.7z
283887 =CP866.7z
287360 =UTF16.7z
292594 =UTF32.7z
303575 =UTF8.7z
327031 =UTF7.7z
335264 =KOI8.9.gz
336010 =KOI8.6.gz
338447 =CP1251.9.gz
338463 =CP866.9.gz
339502 =CP1251.6.gz
339764 =CP866.6.gz
387613 =KOI8.1.gz
391349 =UTF8.9.gz
392584 =CP1251.1.gz
398422 =CP866.1.gz
401381 =UTF8.6.gz
403130 =UTF16.9.gz
419341 =UTF16.6.gz
451425 =UTF7.9.gz
465864 =UTF32.9.gz
474433 =UTF7.6.gz
532714 =UTF32.6.gz
534460 =UTF8.1.gz
555223 =UTF16.1.gz
674206 =UTF7.1.gz
785460 =KOI8.txt
799584 =CP866.txt
799584 =CP1251.txt
841719 =UTF32.1.gz
1349897 =UTF8.txt
1570920 =UTF16.txt
1872210 =UTF7.txt
3141840 =UTF32.txt
)

2
(Важнейшим свойством кодировки UTF-7 является то, что набор используемых значений байтов ограничен. На практике в интернете, когда что-то такое требуется, произвольную последовательность байтов могут кодировать с помощью кодировок Quoted-printable или Base64 (в электронной почте, например). Первая кодировка оставит текст в UTF-7 почти без изменений (и если он был латиницей, то он останется "читаемым"), вторая же что угодно "раздует" примерно на треть и сделает "нечитаемым", даже если было латиницей. Текст кириллицей не будет "читаемым" в UTF-7, а текст кириллицей в остальных шести кодировках кодировать с помощью Quoted-printable крайне неэффективно (может увеличить объём раза в три). Я не привожу в таблице данных о таких кодированиях.)
LinkОставить комментарий

Comments:
[User Picture]
From:[info]lolepezy
Date:August 11th, 2009 - 06:02 pm
(Link)
О!
Интересно.

Думается, UTF-32 не особо распространена из-за проблем с
поддержкой (ну хотя бы просто количественных, скажем, написать
функцию UPPER в какой-нибудь библиотеке уже совсем тривиальная
задача), а не из-за объема.

Объем текста давно никого не волнует, кажется, не видео же.
[User Picture]
From:[info]lolepezy
Date:August 11th, 2009 - 06:03 pm
(Link)
"НЕ совсем тривиальная", конечно
[User Picture]
From:[info]ppkk
Date:August 11th, 2009 - 06:41 pm
(Link)
Так для любой кодировки Юникода проблемы с этой самой "UPPER" будут примерно одинаковыми. Просто кто-то может гордо написать эту функцию для латиницы в UTF-8 и только, а обозвать её, например, utf8upper() — и аналогичное для латиницы в UTF-32 написать ещё проще (не надо даже "парсить" пропускаемые многобайтовые символы, хотя это тоже легко, вообще-то).

Ну и написать "UPPER" для кучи кодировок даже только кириллицы — тоже не очень милое дело.

В плане передачи данных объём волновать может: в четыре раза больше передавать какой-нибудь lib.ru упомянутый вряд ли жаждет.

По-нормальному, чтобы писать "UPPER" или сравнение текста (независимо от регистра и диакритики, а также, наверное, диграфов) для Юникода достаточно прочитать стандарт, а потом ковыряться с файлами описания символов: в итоге это более интеллектуальная работа, чем вбить пару массивов из 256-и элементов. Но вбивать может почти ничего и не потребоваться, да и при обновлении стандарта придётся только перекомпилировать программу (пишется анализатор файлов из стандарта типа "CaseFolding.txt" http://www.unicode.org/Public/UNIDATA/CaseFolding.txt и т.п.).