Cовет — обновите nginx. Или пропатчите. Т.к. он по последней уязвимости у вас убивается в корку. При помощи аб — добро пожаловать в Internal Server Error.
Кстати, случайно наткнулся на ещё одно интересное решение, основанное на встроенном типе box. Итоговый выигрыш — того же порядка, что и ip4r (GIN бы ему :))
postgres=# EXPLAIN ANALYZE SELECT * FROM testip WHERE 19999999 BETWEEN startip AND endip;
QUERY PLAN
----------------------------------------------------------------
Seq Scan on testip (cost=0.00..19902.00 rows=200814 width=12) (actual time=3.457..434.218 rows=1 loops=1)
Filter: ((19999999 >= startip) AND (19999999 <= endip))
Total runtime: 434.299 ms
(3 rows)
Time: 435,865 ms
postgres=# CREATE INDEX ggg ON testip USING gist ((box(point(startip,startip),point(endip,endip))) box_ops);
CREATE INDEX
Time: 75530,079 ms
postgres=# EXPLAIN ANALYZE
SELECT *
FROM testip
WHERE box(point(startip,startip),point(endip,endip)) @> box(point (19999999,19999999), point(19999999,19999999));
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Bitmap Heap Scan on testip (cost=60.50..2550.14 rows=1000 width=12) (actual time=0.169..0.172 rows=1 loops=1)
Recheck Cond: (box(point((startip)::double precision, (startip)::double precision), point((endip)::double precision, (endip)::double precision)) @> '(19999999,19999999),(19999999,19999999)'::box)
-> Bitmap Index Scan on ggg (cost=0.00..60.25 rows=1000 width=0) (actual time=0.152..0.152 rows=1 loops=1)
Index Cond: (box(point((startip)::double precision, (startip)::double precision), point((endip)::double precision, (endip)::double precision)) @> '(19999999,19999999),(19999999,19999999)'::box)
Total runtime: 0.285 ms
(5 rows)
Time: 2,805 ms
Лучший, на мой взгляд, шаблонизатор — это CTPP2/. Очень быстрый, содержит достаточное количество уже встроенных функций по представлению данных (toupper, urlescape, etc) — и можно дописать свои на c++, есть биндинги к php, python, perl.
В 1м бенчмарке был вполне себе кусок данных. Просто там извлекается не только "...", но и key=«value» — это, видимо, и смутило при построении modern.
PS: Формат — xml, от этого никуда не деться. Но если мне пришло что-то, с моей точки зрения, невалидное — я это спокойно отбрасываю. Полная версия парсера — 3 регулярки, на моём подможестве xml скорость примерно такая:
Я согласен с тем, что случай экранирования произвольного количества слешей перед кавычкой ни одна из предложенных мной регулярок не решает. Но для моего случая (я использую lazy_2) — я буду считать пришедшие данные невалидными, если они не соответствуют этой регулярке. Благо я контролирую обе стороны передачи данных :)
Это и ответ на 2й вопрос — про modern. Этот кусок кода — часть xml-парсера (а мне нужно очень небольшое подмножество xml), поэтому внутри кавычек может быть произвольный текст — вариант с [^] не проходит.
Backtracking — механизм «возврата» жадным квалификатором символов входной строки, если текущее (т.е. изначально — до конца строки) его значение не позволяет выполнится всему регулярному выражению. Это иногда удобно — если нам нужен текст между первым < и последним >, то можно написать просто /<.*>/ — и вернётся всё, что нужно. Но чаще бывает другая ситуация — нам нужен какой-то небольшой участок входного текста — первый тег, к примеру. Тогда жадность создаст большие проблемы — съев всю строку.
Жадные модификаторы плохи, когда им приходится возвращать обратно регулярному выражению много, и хороши, когда возвращать почти ничего не придётся. Это правило позволяет определить, когда их стоит использовать, а когда — нет.
По поводу + — иногда надо разрешать пустые участки — к примеру, bb-теги [b][/b] — валидный тег, но внутри ничего нет. Или если во входном тексте пробел — необязательный разделитель ввода.
Низкая производительность не-жадных модификаторов — да, выход из сохраняющих скобок дорог. Но вот возьмём классику — выделить из текста строку между двумя кавычками, с учётом экранирование кавычки слешем. У меня есть пример из «Mastering regular expressions» с использованием жадного варианта [^..]* и мой вариант, через .*? и negative look-behind. Второй — быстрее) Могу привести обе регулярки.
ЗЫ: за bless({}, ref $invocant || $invocant) я бы лично закапывал на месте :) Не должно быть возможности вызвать new() на объекте.
postgres=# EXPLAIN ANALYZE SELECT * FROM testip WHERE 19999999 BETWEEN startip AND endip; QUERY PLAN ---------------------------------------------------------------- Seq Scan on testip (cost=0.00..19902.00 rows=200814 width=12) (actual time=3.457..434.218 rows=1 loops=1) Filter: ((19999999 >= startip) AND (19999999 <= endip)) Total runtime: 434.299 ms (3 rows) Time: 435,865 ms postgres=# CREATE INDEX ggg ON testip USING gist ((box(point(startip,startip),point(endip,endip))) box_ops); CREATE INDEX Time: 75530,079 ms postgres=# EXPLAIN ANALYZE SELECT * FROM testip WHERE box(point(startip,startip),point(endip,endip)) @> box(point (19999999,19999999), point(19999999,19999999)); QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Bitmap Heap Scan on testip (cost=60.50..2550.14 rows=1000 width=12) (actual time=0.169..0.172 rows=1 loops=1) Recheck Cond: (box(point((startip)::double precision, (startip)::double precision), point((endip)::double precision, (endip)::double precision)) @> '(19999999,19999999),(19999999,19999999)'::box) -> Bitmap Index Scan on ggg (cost=0.00..60.25 rows=1000 width=0) (actual time=0.152..0.152 rows=1 loops=1) Index Cond: (box(point((startip)::double precision, (startip)::double precision), point((endip)::double precision, (endip)::double precision)) @> '(19999999,19999999),(19999999,19999999)'::box) Total runtime: 0.285 ms (5 rows) Time: 2,805 ms© www.postgres.cz/index.php/PostgreSQL_SQL_Tricks
Если не к чему придаться — надо придраться к оформлению документации?)
А хабр использует (или использовал) Blitz.
У Сысоева на highload был хороший доклад о настройке FreeBSD на обработку большого числа соединений — вполне применимо к ДДОСу.
PS: Формат — xml, от этого никуда не деться. Но если мне пришло что-то, с моей точки зрения, невалидное — я это спокойно отбрасываю. Полная версия парсера — 3 регулярки, на моём подможестве xml скорость примерно такая:
Rate simple_expat simple_default simple_libxml_sax simpe_parser simple_expat_xs xml_twig tree_parser xml_parser xml_libxml regexp xml_libxml 9754/s 1469% 1072% 673% 658% 645% 619% 230% 176% -- -81% regexp 50355/s 8002% 5952% 3892% 3814% 3747% 3612% 1602% 1324% 416% --Я согласен с тем, что случай экранирования произвольного количества слешей перед кавычкой ни одна из предложенных мной регулярок не решает. Но для моего случая (я использую lazy_2) — я буду считать пришедшие данные невалидными, если они не соответствуют этой регулярке. Благо я контролирую обе стороны передачи данных :)
Это и ответ на 2й вопрос — про modern. Этот кусок кода — часть xml-парсера (а мне нужно очень небольшое подмножество xml), поэтому внутри кавычек может быть произвольный текст — вариант с [^] не проходит.
Поменяв $str на "" — съели все. ЧЯДНТ?)
Насколько я помню этот скрипт — std, plus, unroll все из Mastering RE. Ещё, если перл 5.10 — можно попробовать greedy, но у меня нет его под рукой.
Lazy + negative lb — "(.*?)"(?<! \\")
paste.org.ru/?374ll0
Rate std lazy plus unroll lazy_2 std 14162/s -- -21% -62% -70% -78% lazy 17921/s 27% -- -52% -62% -72% plus 37121/s 162% 107% -- -20% -43% unroll 46690/s 230% 161% 26% -- -28% lazy_2 64631/s 356% 261% 74% 38% --Жадные модификаторы плохи, когда им приходится возвращать обратно регулярному выражению много, и хороши, когда возвращать почти ничего не придётся. Это правило позволяет определить, когда их стоит использовать, а когда — нет.
По поводу + — иногда надо разрешать пустые участки — к примеру, bb-теги [b][/b] — валидный тег, но внутри ничего нет. Или если во входном тексте пробел — необязательный разделитель ввода.
Низкая производительность не-жадных модификаторов — да, выход из сохраняющих скобок дорог. Но вот возьмём классику — выделить из текста строку между двумя кавычками, с учётом экранирование кавычки слешем. У меня есть пример из «Mastering regular expressions» с использованием жадного варианта [^..]* и мой вариант, через .*? и negative look-behind. Второй — быстрее) Могу привести обе регулярки.