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 не указывается длина шаблона.
Интересно, а в mysql кодировка даст такой-же прирост? )
Если смотреть время user (т. е. без чтения файла), то имеем разницу не в 29 раз, а в 1.286/0.004=321 раз. Как-то слишком хорошо для правды.
Btw, а то, что в pcre16_compile передаётся строка не в utf-16, это нормально?
Комментарий для sergey-cheban.livejournal.com:
Ну pcre16_compile выдаёт ошибку, если что-то не так, а тут не выдал. Я сейчас проснусь и попробую передать туда UTF-16.
Комментарий для sergey-cheban.livejournal.com:
Я тут сообразил, что не знаю как передать туда UTF-16. В pcre16_exec есть размер, а в compile размера нет и первый же ноль будет обозначать конец шаблона и весь шаблон будет состоять из одного символа.
В документации пока ничего не виду на эту тему. Я предположил, что сама функция pcre16_compile умеет распознавать конец таких строк и просто нафигачил нулей после каждого символа, компиляция прошла ровно так же, время не изменилось.
Комментарий для sergey-cheban.livejournal.com:
Попробовал сконвертить строку через iconv и потом допреобразовать через pcre16_utf16_to_host_byte_order. Лучше не стало.