Пишу, по большей части, про историю, свою жизнь и немного про программирование.

PCRE и UTF-16

Прочитал в документации по библиотеке PCRE, что с версии 8.30 она поддерживает кодировку UTF-16. Решил сравнить производительность по сравнению с UTF-8. Всё-таки кодировка UTF-16 (почти) фиксированного размера, обрабатывать её сильно проще, чем UTF-8, которая переменной длины.

Написал два примера на Си: один для UTF-8, второй для UTF-16 и запустил, разницу посмотрите сами:

# это я на своём «Маке» скомпилировал
~$ gcc-4.7 -I/usr/local/Cellar/pcre/8.32/include/ -L/usr/local/Cellar/pcre/8.32/lib/ -lpcre -std=c99 -o utf8 utf8.c
~$ gcc-4.7 -I/usr/local/Cellar/pcre/8.32/include/ -L/usr/local/Cellar/pcre/8.32/lib/ -lpcre16 -std=c99 -o utf16 utf16.c

# два файла в разных кодировках, почти 1,5 млн. строк, правда используется далеко не это количество
~$ wc -l utf8.txt
 1424462 utf8.txt
~$ wc -l utf16.txt
 1424462 utf16.txt

~$ time ./utf8
PCRE version: 8.32 2012-11-30
Yes!
…
Yes!

real	0m1.372s
user	0m1.286s
sys	0m0.039s

~$ time ./utf16
PCRE version: 8.32 2012-11-30
Yes!
…
Yes!

real	0m0.048s
user	0m0.004s
sys	0m0.035s

Либо я где-то неверно что-то напрограммировал, либо разница почти в 29 раз!

Лично мне кажется, что API толком не работает и ошибка в том, что в pcre16_compile не указывается длина шаблона.

5 комментариев
aktuba 2013

Интересно, а в mysql кодировка даст такой-же прирост? )

Sergey Cheban (sergey-cheban.livejournal.com) 2013

Если смотреть время user (т. е. без чтения файла), то имеем разницу не в 29 раз, а в 1.286/0.004=321 раз. Как-то слишком хорошо для правды.

Btw, а то, что в pcre16_compile передаётся строка не в utf-16, это нормально?

Евгений Степанищев (bolknote.ru) 2013

Комментарий для sergey-cheban.livejournal.com:

Btw, а то, что в pcre16_compile передаётся строка не в utf-16, это нормально?

Ну pcre16_compile выдаёт ошибку, если что-то не так, а тут не выдал. Я сейчас проснусь и попробую передать туда UTF-16.

Евгений Степанищев (bolknote.ru) 2013

Комментарий для sergey-cheban.livejournal.com:

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

В документации пока ничего не виду на эту тему. Я предположил, что сама функция pcre16_compile умеет распознавать конец таких строк и просто нафигачил нулей после каждого символа, компиляция прошла ровно так же, время не изменилось.

Евгений Степанищев (bolknote.ru) 2013

Комментарий для sergey-cheban.livejournal.com:

Попробовал сконвертить строку через iconv и потом допреобразовать через pcre16_utf16_to_host_byte_order. Лучше не стало.