+  HandyCache форум
|-+  Главная категория» Общие вопросы» Оптимизация правил
Имя пользователя:
Пароль:
Страниц: [1] 2  Все   Вниз
  Отправить эту тему    Печать  
Автор Тема: Оптимизация правил  (Прочитано 16246 раз)
0 Пользователей и 1 Гость смотрят эту тему.
NothingAnother
Beta tester
*****

Репутация: +7/-2
Offline Offline

Сообщений: 434

Spoiler


« : 16 января 2007, 23:58:42 »

mai62
Нередко одно и то же правило можно записать двояко - используя подстановочные символы или регекспы. Какой путь более эффективен?
Например:
+? или .
+pattern или pattern
Что предпочесть?
В основном встречаются два подхода - обработка простых строк непосредственно строчными ф-ями и предварительный перевод простых строк в регекспы с дальнейшей их обработкой в RegExEngine. А как это реализовано в HC?
Сообщить модератору   Записан

Мы тоже не всего читали Шнитке!..
© В. Вишневский
Сергей
Beta tester
*****

Репутация: +9/-2
Offline Offline

Сообщений: 621



« Ответ #1 : 19 января 2007, 16:51:20 »

mai62 говорил, что правила с плюсиком все равно конвертируются в формат регекспов.
Так что лучше сразу ими пользоваться.
Сообщить модератору   Записан
Omni
Новичок
*

Репутация: +0/-0
Offline Offline

Сообщений: 8


« Ответ #2 : 25 января 2008, 12:26:05 »

Приветствую всех!

Несколько вопросов по оптимизации правил.

1. Имеет ли значение длина правила? Т.е. длинное или очень длинное правило отрабатывается медленнее, чем несколько коротких или это не имеет значения? Или наоборот, длинное быстрее, чем куча коротких?

2. "Обычные" правила исполняются быстрее, чем регулярные выражения, или одинаково по скорости?

3. Список правил исполняется всегда последовательно до конца (например, чёрный) или до первого сработавшего правила?

Если какие-то списки исполняются до конца, то рацпредложение: реализовать функцию, которая поднимала бы самые "популярные" правила вверх в списке и опускала редко срабатывающие к концу.
Таким образом будут экономиться ресурсы.

Сообщить модератору   Записан
Михаил
Gold beta tester
*****

Репутация: +337/-14
Offline Offline

Сообщений: 5513



« Ответ #3 : 25 января 2008, 14:14:35 »

3. Давно уже было такое предложение. Не реализовано.
Сообщить модератору   Записан
DenZzz
Модератор
*****

Репутация: +179/-11
Offline Offline

Сообщений: 5589



« Ответ #4 : 25 января 2008, 14:43:31 »

1. Имеет ли значение длина правила? Т.е. длинное или очень длинное правило отрабатывается медленнее, чем несколько коротких или это не имеет значения? Или наоборот, длинное быстрее, чем куча коротких?

mai62 уже отвечал на подобный вопрос так:

Цитировать
Думаю, что если не злоупотреблять, то первый вариант лучше. Правила хранятся в скомпилированном виде, поэтому работают быстро. А на накладных расходах при этом можно сэкономить. К тому же в первом случае можно используя всю мощь синтаксиса регулярных выражений построить более универсальные правила, чем простое пречисление вариантов. С другой стороны нужно помнить, что чрезмерно сложные правила требуют большого расхода ресурсов компьютера и, в первую очередь, памяти.

От себя добавлю, что быстродействие правила зависит в большой степени не от длины, а от наличия в нем ресурсопожирающих конструкций!
Например, опытным путем уже было установлено, что:
  • (.)* из-за многократной рекурсии пожирает гораздо больше ресурсов, чем просто .*
    Это иногда приводило к срабатыванию ограничения на число рекурсий и правило не работало на длинных URL!
    Да и сама конструкция .* потребляет много ресурсов, поэтому не стоит использовать ее там, где нет прямой необходимости, например, в начале и конце правил.
  • Вместо a|c|e лучше использовать [ace] , т.к. это потребляет меньше ресурсов.
  • Конструкция вида a{3} работает медленнее, чем aaa
  • Надо стараться избегать лишних скобок. Например: a(bc|de) съест больше ресурсов, чем abc|ade
    и т.д.
В общем, если нет прямой необходимости, то надо избегать ресурсоемких конструкций!
 
Цитировать
2. "Обычные" правила исполняются быстрее, чем регулярные выражения, или одинаково по скорости?

Простые правила приводятся к виду RegExp перед компиляцией. В любом случае, в памяти и те и другие находятся в скомпилированном виде, поэтому их начальная форма не должна влиять на скорость их работы!

Цитировать
3. Список правил исполняется всегда последовательно до конца (например, чёрный) или до первого сработавшего правила?

Все списки, кроме "Переадресации" и "Преобразование URL", проверяются до первого сработавшего правила.

Цитировать
Если какие-то списки исполняются до конца, то рацпредложение: реализовать функцию, которая поднимала бы самые "популярные" правила вверх в списке и опускала редко срабатывающие к концу.
Таким образом будут экономиться ресурсы.

Такое предложение уже выносилось. Это не первоочередная задача! На данный момент в HC известно несколько других более "узких мест", прямо влияющих на производительность...


Чтобы было примерно понятно, о каких временнЫх затратах идет речь при проверке регулярных выражений приведу несколько своих замеров на Pentium-4 2.8:
^content-length: (\d*) - 0,0000111 сек
^content-length:\s*(\d*)\s*$ - 0,0000121 сек
Т.е. чуть больше 1 секунды на 100000 проверок! ИМХО, это крайне маленькая величина, чтобы бить тревогу по этому поводу!
Сообщить модератору   Записан
Omni
Новичок
*

Репутация: +0/-0
Offline Offline

Сообщений: 8


« Ответ #5 : 25 января 2008, 16:15:06 »

Спасибо за разъяснение. Но как быть в таком случае со списком замены, если необходимо заметить строку полностью, в случе, если правило сработало? Ведь нам необходимо каким-то образом обозначить всю строку, т.е. и в начале, и в конце выражения появляются .* , которые, как вы говорите, ресурсоёмки.
А если таких строк несколько десятков? Не замедлит ли это проверку списка?

Не сделать ли в таком случае специальный флажок "заменить полностью"? Это исключит использование конструкции .* по два раза в каждой строке.

Хотя в свете приведённых вами цифр все эти усилия могут оказаться напрасными из-за микроскопической разницы. Или это всё же не так?
« Последнее редактирование: 25 января 2008, 16:33:29 от Omni » Сообщить модератору   Записан
DenZzz
Модератор
*****

Репутация: +179/-11
Offline Offline

Сообщений: 5589



« Ответ #6 : 25 января 2008, 16:46:55 »

Ведь нам необходимо каким-то образом обозначить всю строку, т.е. и в начале, и в конце выражения появляются .* , которые, как вы говорите, ресурсоёмки.

Я говорил: "не стоит использовать ее там, где нет прямой необходимости"! В "Переадресации" и "Преобразовании URL" такая необходимость может возникнуть, а, например, в начале и конце правил "Черного списка" - нет!

Цитировать
Не сделать ли в таком случае специальный флажок "заменить полностью"? Это исключит использование конструкции .* по два раза в каждой строке.

В этом нет необходимости! Для работы данной опции HC будет использовать все тот же RegExp! Кроме того, я уже говорил, что разница в быстродействии не всегда столь существенна - в примере выше добавление двух похожих конструкций \s* увеличило время проверки всего на 0,000001 секунды - это мизер!
Сообщить модератору   Записан
DenZzz
Модератор
*****

Репутация: +179/-11
Offline Offline

Сообщений: 5589



« Ответ #7 : 25 января 2008, 17:49:51 »

Сделал несколько замеров времени работы некоторых выражений в цикле для URL разной длины:

RegExpURL 250 символовURL 100 символов
aaaaa0.0000059 сек0.0000058 сек
.*aaaaa0.0000126 сек0.0000075 сек
.*aaaaa.*0.0000144 сек0.0000079 сек
(.)*aaaaa0.0000532 сек0.0000231 сек
(.)*aaaaa(.)*0.0000788 сек0.0000261 сек
.*(a|c|e).*0.0000267 сек0.0000101 сек
.*[ace].*0.0000117 сек0.0000078 сек
a{3}0.0000061 сек0.0000049 сек
aaa0.0000060 сек0.0000048 сек
a(bc|de)0.0000072 сек0.0000069 сек
abc|ade0.0000064 сек0.0000061 сек
Сообщить модератору   Записан
Omni
Новичок
*

Репутация: +0/-0
Offline Offline

Сообщений: 8


« Ответ #8 : 25 января 2008, 18:39:22 »

Для работы данной опции HC будет использовать все тот же RegExp!

Вы не правы. Для данной опции в использовании регэкспов конечно нет необходимости, так как весь урл просто заменяется на указанную строку.

Впрочем, вы наглядно показали, что "работы по оптимизации" не дадут ощутимого выигрыша в случае среднего пользователя. Однако если правил очень много, всё-таки выигрыш будет.
Сообщить модератору   Записан
DenZzz
Модератор
*****

Репутация: +179/-11
Offline Offline

Сообщений: 5589



« Ответ #9 : 25 января 2008, 19:06:24 »

Для данной опции в использовании регэкспов конечно нет необходимости, так как весь урл просто заменяется на указанную строку.

Все равно надо будет проверить соответствие правила! Нам же не надо заменять любой URL на новый.
Вообще, многие функции HC используют RegExp в своей работе! В частности URL передается на сервер/клиенту не в чистом виде, а внутри заголовков запроса/ответа. Чтобы вычленить этот URL из заголовка и вклеить назад измененный используется RegExp! Поэтому от использования регулярных выражений все равно никуда не деться!

Однако если правил очень много, всё-таки выигрыш будет.

На глаз не заметишь! В ФАКе это уже тестировали! Вообще, узкое место HC на данный момент - это вывод в Монитор, формирование логов и дисковые операции...
Сообщить модератору   Записан
Omni
Новичок
*

Репутация: +0/-0
Offline Offline

Сообщений: 8


« Ответ #10 : 25 января 2008, 19:25:57 »

Ясно, т.е. вы рекомендуете отключить логи и монитор для обычной работы?
Сообщить модератору   Записан
DenZzz
Модератор
*****

Репутация: +179/-11
Offline Offline

Сообщений: 5589



« Ответ #11 : 25 января 2008, 19:53:19 »

Да, общие рекомендации для снижения потребления ресурсов:

- Отключить ведение лога: "Общие / Вид / Вести лог".
- В "Ограничить количество записей в мониторе" поставить 1000.
- В настройках списков включить опцию "Не показывать соединения в мониторе".
- Сворачивать HC в трей, когда Монитор не используется.
Сообщить модератору   Записан
Михаил
Gold beta tester
*****

Репутация: +337/-14
Offline Offline

Сообщений: 5513



« Ответ #12 : 25 января 2008, 22:38:42 »

Да. Много зависит от способа написания правила. Эти моменты будут особо актуальны, если НС когда-нибудь начнет фильтровать HTML-контент.
Сейчас тоже можно исполнить сильно замедляющие работу и жрущие память правила.
К примеру, задать в тренажере простейшее с виду правило
(a+)*s|N
Задать очень короткую входную строку
aaaaaaaaaaaaaaN
DenZzz
Можешь померить, за какое время сработает это правило на указанной строке? Интересно.
Если добавить в начало входной строки еще одну "a", то тренажер (или сама PCRE) уже не справится с задачей.
(Опять же, очень жаль, что тренажер нам об этом никак не диагностирует).
Сообщить модератору   Записан
DenZzz
Модератор
*****

Репутация: +179/-11
Offline Offline

Сообщений: 5589



« Ответ #13 : 25 января 2008, 23:12:32 »

Можешь померить, за какое время сработает это правило на указанной строке?

0,0076 сек. С дополнительной a - 0,0153 сек. С двумя дополнительными а - 0,0336 сек и т.д. с каждой новой a время удваивается!
Сообщить модератору   Записан
Михаил
Gold beta tester
*****

Репутация: +337/-14
Offline Offline

Сообщений: 5513



« Ответ #14 : 26 января 2008, 00:05:14 »

0,0076 сек. С дополнительной a - 0,0153 сек. С двумя дополнительными а - 0,0336 сек и т.д. с каждой новой a время удваивается!
Да. Познавательный результат.
Если кто-то захочет добраться в УРЛе до первого знака вопроса, а если его нет, то до слэша правилом
^(\w+|[./-])*\?|/
то получит фактическое несрабатывание правила на большинстве УРЛов, хотя логически оно должно срабатывать. Для тех из них, на которых оно все-таки будет срабатывать, обработка правила будет занимать значительное время.
Вообще всегда, когда это возможно, надо избегать операций повторения над операциями повторения, а также избегать при повторениях захватов подстроки (употребления простых круглых скобок).
« Последнее редактирование: 26 января 2008, 00:20:32 от Михаил » Сообщить модератору   Записан
Omni
Новичок
*

Репутация: +0/-0
Offline Offline

Сообщений: 8


« Ответ #15 : 26 января 2008, 00:50:34 »

Сейчас тоже можно исполнить сильно замедляющие работу и жрущие память правила.
К примеру, задать в тренажере простейшее с виду правило
(a+)*s|N

Такое правило можно считать ошибкой кодирования. Именно по той причине, что оно очевидно не оптимально, такой код избыточен.

С другой стороны, можно сделать вывод, что сам механизм исполнения правил пока, видимо, не очень оптимизирован по скорости, если такие несложные обработки на строках ничтожной длины занимают значительное время.
Сообщить модератору   Записан
Михаил
Gold beta tester
*****

Репутация: +337/-14
Offline Offline

Сообщений: 5513



« Ответ #16 : 26 января 2008, 01:09:25 »

можно сделать вывод, что сам механизм исполнения правил пока, видимо, не очень оптимизирован по скорости, если такие несложные обработки на строках ничтожной длины занимают значительное время.
Неправильный вывод. На самом деле все ОЧЕНЬ оптимизировано по скорости. Сомневаюсь даже, существует ли более быстрая версия движка регулярных выражений. Просто этим нехитрым с виду правилом задается сильнейшая рекурсия. На практике списки из нескольких сотен правил обрабатываются целиком за доли секунды.
Сообщить модератору   Записан
Omni
Новичок
*

Репутация: +0/-0
Offline Offline

Сообщений: 8


« Ответ #17 : 26 января 2008, 01:49:32 »

Понятно. Ну что ж, это может только радовать, если так.
Сообщить модератору   Записан
Omni
Новичок
*

Репутация: +0/-0
Offline Offline

Сообщений: 8


« Ответ #18 : 26 января 2008, 11:33:51 »

Если кто-то захочет добраться в УРЛе до первого знака вопроса, а если его нет, то до слэша правилом
^(\w+|[./-])*\?|/
то получит фактическое несрабатывание правила на большинстве УРЛов

Сложно представить, что кто-то может реально использовать нечто подобное монстрообразное Улыбка
Сообщить модератору   Записан
DenZzz
Модератор
*****

Репутация: +179/-11
Offline Offline

Сообщений: 5589



« Ответ #19 : 26 января 2008, 11:50:45 »

Если кто-то захочет добраться в УРЛе до первого знака вопроса, а если его нет, то до слэша правилом
^(\w+|[./-])*\?|/

Время выполнения на строке: handycache.ru/components/  - 0,441 сек
При увеличении входящей строки библиотека PCRE в Lua выдает ошибку PCRE_ERROR_MATCHLIMIT:

Цитировать
The default limit for the library can be set when PCRE is built; the default is 10 million, which handles all but the most extreme cases.


Что интересно, если бы входная строка была с протоколом: http://handycache.ru/components/ , то время выполнения этого выражения всего - 0,0000146 сек.
Сообщить модератору   Записан
Страниц: [1] 2  Все   Вверх
  Отправить эту тему    Печать  

 
Перейти в: