FreeBSD: UTF-8 russian collate (вторая попытка)

Несколько дней назад я опубликовал исходник LC_COLLATE для кодировки ru_RU.UTF-8 для использования в FreeBSD. Там же я обещал, что если понадобится не "универсальная" сортировка, а такая же, как в FreeBSD, то сделаю и ее, а обещания нужно выполнять.

Помимо этого, старый вариант не имел вообще никаких шансов попасть в FreeBSD (причины этого мне объяснил Андрей Чернов: нарушается FreeBSD-шное правило, что большие буквы отдельно, а маленькие - отдельно), а новый - такие шансы еще не потерял.

Файлы с исходниками табличек

(URL старые, таким образом старый вариант с только табличкой "универсальной" сортировки более не существует)

Установка

tar xzvf ru_RU.UTF-8.LC_COLLATE.tar.gz
cd ru_RU.UTF-8.LC_COLLATE
less README.koi8
make freebsdsort или make universal
su
make install
Старая табличка LC_COLLATE будет сохранена как LC_COLLATE.orig (и не перезаписана при нескольких make install подряд)

Разнообразные соображения

Быстродействие

strcoll для не-однобайтовых таблиц символов сделан в FreeBSD крайне неэффективно. Я померял производительность на романе "Война и Мир", перекодированном в UTF-8 (4.5 мегабайта, 40 тыс строк, sort запускался с -S 100):

  • LANG=C - 0.09 сек.
  • LANG=ru_RU.KOI8-R - 0.27 сек (понятно, что сортировка UTF-8 текста с такой locale непоказательна, но вариант в KOI8-R сортируется 0.23 секунды).
  • LANG=ru_RU.UTF-8 старый (неправильный) вариант LC_COLLATE - 0.31 сек.
  • LANG=ru_RU.UTF-8 с новым вариантом (freebsdsort) - 2.55 сек.
Ничего хорошего, в сравнении с однобайтовой кодировкой теряем почти в 10 раз, это место в FreeBSD очевидно нуждается в переделке.

Поддержка символов из других алфавитов

Таблица freebsdsort сделана перекодировкой таблицы для ru_RU.CP1251 и содержит, таким образом поддерживаются украинские-белорусские-македонские-сербские буквы. Однако порядок сортировки для русского и украинского - отличается (по меньшей мере, судя по исходникам colldef для этих языков для CP1251) , следовательно применение ru_RU к украинском языку будет неправильным.

Другие языки и таблицы символов

Если кому нужен скриптик, который делает из однобайтовой colldef версию для UTF8 - пишите. Он сделан на коленке, но вроде работает.

Comments

И чего только люди не делают лишь бы не использовать linux :)

Я, кстати, потестировался на федоре-8.

С установленной UTF-локалью сортировка utf-8-текста гораздо быстрее, чем на FreeBSD с utf8(что неудивительно). Типа полсекунды.

Но при этом не-utf-8-текст (я подсовывал ту же Войну и Мир в 1251) сортируется (с UTF-locale) чудовищно долго. Еще в 5 раз медленнее, чем FreeBSD.

Мораль - если сортируются бинарные данные, то надо LANG=C sort ....

На сколько мне помнится, julik писал о подобных граблях еще в 2005 году: http://live.julik.nl/2005/04/unicode-and-postgresql.

Он писал как у него не работает, а я пишу как починить. Почувствуйте разницу.