SlideShare a Scribd company logo
1 of 67
© 2015 NetCracker Technology Corporation Confidential
Выражаемся регулярно
Владимир Ситников
JPoint 2015
2© 2015 NetCracker Technology Corporation Confidential
О себе
• Владимир Ситников, @VladimirSitnikv
• Инженер по производительности в NetCracker
• 8 лет опыта с Java/SQL
• Мои предложения принимались в j.l.String,
j.u.c.CopyOnWriteArrayList, jmh
3© 2015 NetCracker Technology Corporation Confidential
План
•Небольшое введение
•Разгоняем /.*/ и /.*?/
•Устраняем StackOverflowError
•Regexp vs XPath
•ANTLR, VTD-XML – не на этом докладе
4© 2015 NetCracker Technology Corporation Confidential
Regexp
he com̡e̶s, ̕h̵i s un̨ho͞ly radiańcé destro҉ying all enli̍̈́̂̈́̍̈́̂̈́
ghtenment, HTML
tags lea͠ki̧n ͘g fr̶ǫm ̡yo ͟ur eye͢s̸ ̛l̕ik͏e liq uid pain, the song of re̸gular exp
ression parsing will exti nguish the voices of mor tal man from the sp
here I can see it can you see î̩́t̲́̋̀t̲́̋̀ it is beautiful t he final snuffing of the
lie s of Man ALL IS LOS
͖̩͇̗̪́̏̈́
T ALL I S LOST the pon̷y he comes he c̶̮omes he
comes the ich or permeates all MY FACE MY FACE ᵒh god no NO
NOO̼O O NΘ stop the an *̶͑̾̾ g͇̫͛͆̾ͫ̑͆l
̲͖͉̗̩̳̟́̋̀̍ͫͥͨ
e̠̅s ͎a̧͈͖r
̽̾̈́͒͑
e n ot rè
̑ͧ̌
aͨl
̘̝̙̃ͤ͂̾̆
ZA̡͊͠͝LGΌ IS
ͮ̂҉̯͈͕̹̘̱
TO͇̹̺ͅƝ̴ȳ̳
TH̘Ë͖́̉ ͠P̯͍̭O̚N̐Y̡ H̡Ȩ̬̩̾͛ͪ̈́̀́͘ ̶ͮ̂҉̯͈͕̹̘̱̯͍̭C
ͭ̏ͥ
̷̙̲̝͖̘̝̙ͮ̃ͤ͂̾̆͟
͖̈́̉
OM̚
͊̒ͪͩͬ̚
̖̚͜E̴̟̟͙̞͌͝S̨
̨͎̥̫͎̭ͯ̿̔̀ͅ
5© 2015 NetCracker Technology Corporation Confidential
Случаи использования regexp
• Анализ success/fail в логах, xml ответа
• Поиск “<status>success</status>”
• Засекречивание паролей при логировании
• Замена “password=(.*)” на “password=****”
• По неосторожности
6© 2015 NetCracker Technology Corporation Confidential
Случаи использования regexp
• Анализ success/fail в логах, xml ответа
• Поиск “<status>success</status>”
• Засекречивание паролей при логировании
• Замена “password=(.*)” на “password=****”
• По неосторожности (String.replaceAll и т.п.)
7© 2015 NetCracker Technology Corporation Confidential
Две проблемы
•У вас проблема, и вы собрались
использовать регулярные выражения
для её решения
•Теперь у вас две проблемы
8© 2015 NetCracker Technology Corporation Confidential
Ужасы нашего городка
9© 2015 NetCracker Technology Corporation Confidential
Что не так с .* ?
•Обычно, regexp библиотеки работают
«методом перебора»
•Если хвост «не подошёл», откатим
попробуем Regexp ещё раз
10© 2015 NetCracker Technology Corporation Confidential
/^.*ab$/.match("ab")
|ab
.*ab
a|b
.*ab
ab|
.*ab
ab|
.*ab
a|b
.*ab
откатились
a|b
.*ab
не помогло
|ab
.*ab
откатились
ab|
.*ab
Ура!
.* – жадная конструкция. Ест как не в себя
11© 2015 NetCracker Technology Corporation Confidential
Ленивые вычисления спешат на помощь
•Ленивый вариант помогает в конкретном
случае
/^.*?abc$/.match("abc")
•Но помогает далеко не всегда
12© 2015 NetCracker Technology Corporation Confidential
/^.*?b$/.match("aaa")
|aab
.*?ab
a|ab
.*?ab
a|ab
.*?ab
|aab
.*?ab
откатились
a|ab
.*?ab
aa|b
.*?ab
aab|
.*?ab
Ура!
.*? – ленивая конструкция
13© 2015 NetCracker Technology Corporation Confidential
Ленивые вычисления и реальность
•Если regexp не подходит к строке, то всё
равно придётся рассмотреть все случаи
•Был случай, что выражение вида
<.*:item.*>(.*)</.*:item> работало
30 секунд на 100 КиБ строке
14© 2015 NetCracker Technology Corporation Confidential
Ленивые вычисления и реальность
<.*?:item.*?>(.*?)</.*?:item>
Уже лучше, regexp engine всё равно будет
откатываться при выполнении .*
15© 2015 NetCracker Technology Corporation Confidential
Ужасы нашего городка
16© 2015 NetCracker Technology Corporation Confidential
Ленивые вычисления и реальность
<[^:>]*:item[^>]*>([^<]*)</...
[^>] не выйдет за границы XML тэга,
вариантов будет намного меньше, и
работать будет гораздо быстрее
17© 2015 NetCracker Technology Corporation Confidential
Сравним 3 варианта
• <ROW>.*<ACCNT>.*</ACCNT>.*</ROW>
• <ROW>.*?<ACCNT>.*?</ACCNT>.*?</ROW>
• <ROW>.*?<ACCNT>[^<]*</ACCNT>.*?</ROW>
18© 2015 NetCracker Technology Corporation Confidential
График скорости .*, .*?, [^>]
0
100
200
300
400
1 КиБ 2 КиБ 3 КиБ 4 КиБ
Быстрее,оп/мс
.*
.*?
[^>]*
19© 2015 NetCracker Technology Corporation Confidential
График скорости .*, .*?, [^>], шаблон не найден
0
10
20
30
40
50
1 КиБ 2 КиБ 3 КиБ 4 КиБ
Быстрее,оп/мс
.*
.*?
[^>]*
Поиск тормозил, т.к.
шаблон не нашёлся
20© 2015 NetCracker Technology Corporation Confidential
JPoint или Joker?
Pattern.compile("(Joker|JPoint)+")
• На строке "JokerJPoint…700раз…Joker"
падает с ошибкой StackOverflowError
• Как так?
21© 2015 NetCracker Technology Corporation Confidential
JPoint или Joker?
java.lang.StackOverflowError
.regex.Pattern$BranchConn.match(Pattern.java:4568
.regex.Pattern$Slice.match(Pattern.java:3972)
.regex.Pattern$Branch.match(Pattern.java:4604)
.regex.Pattern$GroupHead.match(Pattern.java:4658)
.regex.Pattern$Loop.match(Pattern.java:4785)
.regex.Pattern$GroupTail.match(Pattern.java:4717)
.regex.Pattern$BranchConn.match(Pattern.java:4568
22© 2015 NetCracker Technology Corporation Confidential
JPoint или Joker?
Pattern.compile("(Joker|JPoint)+?")
• Добавим "?". Помогло?
• Падать перестало, но теперь посещаем только
первую конференцию из всех
23© 2015 NetCracker Technology Corporation Confidential
Однажды в NetBeans
NetBeans Bug 154894 - StackOverflowError at
java.util.regex.Pattern$SliceI.match
support/JavadocAndSourceRootDetection.java
String whitespace = "…(?:[^*]|*[^/])*…"
24© 2015 NetCracker Technology Corporation Confidential
JPoint или Joker?
Pattern.compile("(Joker|JPoint)+")
• Regexp engine оставляет шанс отката для
проверки альтернативной ветки
• В OpenJDK Pattern использует ООП java stack,
при большой вложенности и получается
StackOverflow
25© 2015 NetCracker Technology Corporation Confidential
Можно ли избавиться от откатов?
Без откатов крайне сложно (невозможно?)
сделать
26© 2015 NetCracker Technology Corporation Confidential
Можно ли избавиться от откатов?
Без откатов крайне сложно (невозможно?)
сделать back-references:
(.*)1
aa, abab, abcabc, …
27© 2015 NetCracker Technology Corporation Confidential
Как это выглядит в документации
Greedy Reluctant Posessive Значение
X? X?? X?+ X, один раз или ни единого
X* X*? X*+ X, ноль или более раз
X+ X+? X++ X, один или более раз
X{n} X{n}? X{n}+ X, ровно n раз
X{n,} X{n,}? X{n,}+ X, как минимум n раз
X{n,m} X{n,m}? X{n,m}+ X, от n до m раз
https://docs.oracle.com/javase/tutorial/essential/regex/quant.html
28© 2015 NetCracker Technology Corporation Confidential
Чего-чего?
29© 2015 NetCracker Technology Corporation Confidential
А на это мало кто обращает внимание
Greedy Reluctant Posessive Значение
X? X?? X?+ X, один раз или ни единого
X* X*? X*+ X, ноль или более раз
X+ X+? X++ X, один или более раз
30© 2015 NetCracker Technology Corporation Confidential
С++ спешит на помощь
Pattern.compile("(Joker|JPoint)++")
• ++ и *+ отключает откаты, и это как раз то, что
нужно
31© 2015 NetCracker Technology Corporation Confidential
«Мне повезёт»
Pattern.compile("(?>Joker|JPoint)+")
?> – режим, при котором все откаты внутри
скобок «забываются». Первый совпавший
вариант принимается как окончательный
32© 2015 NetCracker Technology Corporation Confidential
График скорости .*, .*, [^>], шаблон не найден
0
20
40
60
80
100
1 КиБ 2 КиБ 3 КиБ 4 КиБ
Быстрее,оп/мс
.*
.*?
[^>]*
(?>
<ROW>(?>.*?<RSACCTNMBR>)
(?>[^<]*</RSACCTNMBR>)…
33© 2015 NetCracker Technology Corporation Confidential
/(?>ab|a)b/.match("a")
|ab
(?>ab|a)b
a|b
(?>ab|a)b
ab|
(?>ab|a)b
ab|
(?>ab|a)b
ab|
(?>ab|a)b
Шаблон не
найден
(?>ab|a) не будет проверять второй вариант
34© 2015 NetCracker Technology Corporation Confidential
А давайте ускорим String?
• String.format("...") использует
java.util.regex.Pattern для разбора формата
formatSpecifier = "%(d+$)?([-#+
0,(<]*)?(d+)?(.d+)?([tT])?([a-
zA-Z%])";
35© 2015 NetCracker Technology Corporation Confidential
Откуда взять тестовые данные?
Возьмём шаблон из самого JMH:
(min, avg, max) = (%s, %s, %s), stdev = %s%n
CI (99.9%%): [%s, %s] (assumes normal
distribution)
36© 2015 NetCracker Technology Corporation Confidential
А давайте ускорим String?
formatSpecifier = "%(d+$)?([-#+
0,(<]*)?(d+)?(.d+)?([tT])?([a-
zA-Z%])";
fastSpecifier = "%(d++$)?+([-#+
0,(<]+)?+(d++)?+(.d++)?+([tT])?+([a-zA-
Z%])";
37© 2015 NetCracker Technology Corporation Confidential
Бесплатный сыр
Benchmark Cnt Score Error Units
jdk18u45 60 1,067 ± 0,025 us/op
optimized 60 0,917 ± 0,021 us/op
38© 2015 NetCracker Technology Corporation Confidential
NetBeans, NetBeans
(?>[^*]|*[^/])
Работает?
39© 2015 NetCracker Technology Corporation Confidential
NetBeans, NetBeans
(?>[^*]|*[^/])
StackOverflow не бросит, а на /***/ не сработает
40© 2015 NetCracker Technology Corporation Confidential
NetBeans, NetBeans
(?>[^*]|*(?!/))
Вот это уже сработает!
(?!/) – negative lookahead
41© 2015 NetCracker Technology Corporation Confidential
Признаки плохого регулярного выражения
• Неспецифичные символы
• .*
• Внутри группировок
• Повторения: (a+)+, ([a-zA-Z]+)*=
• Альтернативы с пересечениями: (a|aa)+, (a|a?)+
42© 2015 NetCracker Technology Corporation Confidential
А можно ли совсем без откатов?
Если отказаться от back-references, то есть быстрые
алгоритмы
Детерминированный
конечный автомат
для /(1|01*0)*/
43© 2015 NetCracker Technology Corporation Confidential
Современные regexp библиотеки в java
Название Год выпуска Алгоритм
java.util.regex.Pattern 2015 backtrack
com.basistech.tclre 2015 DFA
org.jruby.joni (Nashorn) 2014 backtrack
Apache Oro 2000 backtrack
JRegex 2013 backtrack
44© 2015 NetCracker Technology Corporation Confidential
Современные regexp библиотеки в смежных языках
Название Версия Алгоритм
Oracle 12с backtrack
PostgreSQL 9.3 DFA
MySQL 5.6 DFA
JavaScript/Chrome 43 backtrack
JavaScript/FireFox 48 backtrack
Python/Ruby/Perl/PHP backtrack
45© 2015 NetCracker Technology Corporation Confidential
Как проверить backtrack?
/(x+x+)+y/.test("xxxxx…20 раз…xxx")
Если regexp с откатами, то он будет очень долго
подбирать x+
46© 2015 NetCracker Technology Corporation Confidential
/(x+x+)+y/.test("xxxx…xxx")
0
500
1000
1500
2000
5 6 7
Быстрее,op/ms
java
joni
tcl
jregex
47© 2015 NetCracker Technology Corporation Confidential
/(x+x+)+y/.test("xxxx…xxx")
50 1 112 4 1
1240 1185 1151
21 0.07 0.02
0
500
1000
1500
10 15 20
Быстрее,op/ms
java
joni
tcl
jregex
48© 2015 NetCracker Technology Corporation Confidential
<ROW>(?>.*?<RSACCTNMBR>)(?>[^<]*</RSACCTNMBR>)
30
5
1
0.4
23
4 1 0.4
42
9
3 1
95
47
31
2426 26 25 25
0
20
40
60
80
100
1 КиБ 2 КиБ 3 КиБ 4 КиБ
Быстрее,op/ms
.*
.*?
[^>]*
(?>
tcl, [^>]*
49© 2015 NetCracker Technology Corporation Confidential
50© 2015 NetCracker Technology Corporation Confidential
CPU vs memory
• DFA подход потребляет больше памяти
• Патчим jmh, и там появляется allocation profiler
51© 2015 NetCracker Technology Corporation Confidential
CPU vs memory: <row>…
0.2 0.2 0.2 0.2
32 32 32 32
0
10
20
30
40
1 КиБ 2 КиБ 3 КиБ 4 КиБ
Память,КиБ/op
java
tcl
Pattern#matcher потребляет всего 200 байт
52© 2015 NetCracker Technology Corporation Confidential
CPU vs memory: <row>…
0 0 0 0
32 32 32 32
0
10
20
30
40
1 КиБ 2 КиБ 3 КиБ 4 КиБ
Память,КиБ/op
java
tcl
При Matcher#reset память вообще отдыхает
53© 2015 NetCracker Technology Corporation Confidential
j.l.r.Pattern
• Поддерживает Unicode (java 1.7+)
• Управляемый откат
• Малое потребление памяти
54© 2015 NetCracker Technology Corporation Confidential
org.jruby.Joni
• Поддерживает Unicode
• Управляемый откат
• Может работать с byte[] в UTF-8 кодировке
• Поддерживает Thread#interrupt()
• Малое потребление памяти
55© 2015 NetCracker Technology Corporation Confidential
Tcl-re
• DFA алгоритм, стабильное время работы
• Не самая быстрая на простых шаблонах
• Большое потребление памяти
56© 2015 NetCracker Technology Corporation Confidential
Они всё ещё разбирают XML regexp’ами
57© 2015 NetCracker Technology Corporation Confidential
Сравним с XPath
• Парсинг XML (20, 40, 60КиБ)
• Поиск тэга по точному пути
• Замена пароля звёздочками (поиск по
имени атрибута)
58© 2015 NetCracker Technology Corporation Confidential
XPath
• Парсинг XML
• Поиск тэга по точному пути
• ICOMS/MAC00029/@ACNT
• Замена пароля звёздочками (поиск по
имени атрибута)
• //self::node()[@__hPINNMBR]
59© 2015 NetCracker Technology Corporation Confidential
Regexp
• Парсинг XML
• Поиск тэга по точному пути, все вхождения
• <MAC00029(?:.(?! ACNT))*+ ACNTN="([^"]*+)"
• Замена пароля звёздочками (поиск по имени
атрибута, все вхождения)
• __hPINNMBR="[^"]*+"
60© 2015 NetCracker Technology Corporation Confidential
Тестовая среда
• Java 1.8u45, JMH 1.9
• Встроенный XPath
• newXPath().compile
• xpath.evaluate(parsedXml,
XPathConstants.NODESET)
• Intel Core i7-4960HQ CPU @ 2.60GHz
61© 2015 NetCracker Technology Corporation Confidential
CPU: XML vs Pattern
6 3 1
8 7 43 4 2
67
35
15
79
38
24
0
20
40
60
80
100
20 КиБ 40 КиБ 60 КиБ
Быстрее,оп/мс
xmlParse
xpExact
xpSearch
reExact
reSearch
j.u.r.Pattern
62© 2015 NetCracker Technology Corporation Confidential
Heap: XML vs Pattern
86
167
266
299 310
358
500
319
370
0.2 0.2 0.20.2 0.2 0.2
0
200
400
600
20 КиБ 40 КиБ 60 КиБ
Память,КиБ/oп
xmlParse
xpExact
xpSearch
reExact
reSearch
63© 2015 NetCracker Technology Corporation Confidential
Полмегабайта на xpath
• Где моя память, чувак?!
.jvmArgs("-XX:+UnlockCommercialFeatures",
"-XX:+FlightRecorder",
"-XX:StartFlightRecording=duration=60s,"
+ "settings=profile,"
+ "filename=xpathExact_60k.jfr")
64© 2015 NetCracker Technology Corporation Confidential
JFR показывает кто виноват
Java FlightRecorder показывает, что виноват XPathContext
65© 2015 NetCracker Technology Corporation Confidential
One way ticket, one way ticket, …
JDK-6344064 Potential XPath performance issue in
"new XPathContext()".
Fresh XPathContext is created for each call to
evaluate(). However, the way the API is set up now,
it is difficult not to do this. I'm assuming that the
use case is having a W3C DOM and evaluating
multiple XPath expressions on it.
66© 2015 NetCracker Technology Corporation Confidential
Заключение
• (?>…), ++, *+, ?+ отключают backtracking, что
сильно ускоряет regexp
• В простых случаях java.util работает быстро
• Точный XPath работает быстрее Pattern, но
аллоцирует уйму памяти
© 2015 NetCracker Technology Corporation Confidential
Вопросы?
Владимир Ситников,
JPoint 2015

More Related Content

What's hot

Производительность open source решений
Производительность open source решенийПроизводительность open source решений
Производительность open source решенийVladimir Sitnikov
 
Быстрое построение backendов c помощью реактивных потоков
Быстрое построение backendов c помощью реактивных потоковБыстрое построение backendов c помощью реактивных потоков
Быстрое построение backendов c помощью реактивных потоковCodeFest
 
Zabbix 3.4 - простая непростая дружба с сообществом / Алексей Владышев (Zabbix)
Zabbix 3.4 - простая непростая дружба с сообществом / Алексей Владышев (Zabbix)Zabbix 3.4 - простая непростая дружба с сообществом / Алексей Владышев (Zabbix)
Zabbix 3.4 - простая непростая дружба с сообществом / Алексей Владышев (Zabbix)Ontico
 
Организация процесса регулярной обработки больших объемов данных
Организация процесса регулярной обработки больших объемов данныхОрганизация процесса регулярной обработки больших объемов данных
Организация процесса регулярной обработки больших объемов данныхCodeFest
 
Kubernetes
KubernetesKubernetes
KubernetesSQALab
 
Реактивный двигатель вашего Android приложения
Реактивный двигатель вашего Android приложенияРеактивный двигатель вашего Android приложения
Реактивный двигатель вашего Android приложенияMatvey Malkov
 
Deployment to production with an unexpected load
Deployment to production with an unexpected loadDeployment to production with an unexpected load
Deployment to production with an unexpected loadGrid Dynamics
 
Zabbix 3.2 - мониторинг качественно нового уровня / Алексей Владышев (Zabbix)
Zabbix 3.2 - мониторинг качественно нового уровня / Алексей Владышев (Zabbix)Zabbix 3.2 - мониторинг качественно нового уровня / Алексей Владышев (Zabbix)
Zabbix 3.2 - мониторинг качественно нового уровня / Алексей Владышев (Zabbix)Ontico
 
Selenium grid on-demand
Selenium grid on-demandSelenium grid on-demand
Selenium grid on-demandSQALab
 
Алексей Романчук «Реактивное программирование»
Алексей Романчук «Реактивное программирование»Алексей Романчук «Реактивное программирование»
Алексей Романчук «Реактивное программирование»DevDay
 
Сенцов Сергей "Приемы оптимизаций Desktop приложений"
Сенцов Сергей "Приемы оптимизаций Desktop приложений"Сенцов Сергей "Приемы оптимизаций Desktop приложений"
Сенцов Сергей "Приемы оптимизаций Desktop приложений"Yulia Tsisyk
 
Что нам стоит DAL построить? Акуляков Артём D2D Just.NET
Что нам стоит DAL построить? Акуляков Артём D2D Just.NETЧто нам стоит DAL построить? Акуляков Артём D2D Just.NET
Что нам стоит DAL построить? Акуляков Артём D2D Just.NETDev2Dev
 
Олег Миколайченко "Как перестать хранить секреты в git и начать использовать ...
Олег Миколайченко "Как перестать хранить секреты в git и начать использовать ...Олег Миколайченко "Как перестать хранить секреты в git и начать использовать ...
Олег Миколайченко "Как перестать хранить секреты в git и начать использовать ...Fwdays
 
Всевидящее око. Мониторинг нагрузочного тестирования с InfluxDB и Grafana
Всевидящее око. Мониторинг нагрузочного тестирования с InfluxDB и GrafanaВсевидящее око. Мониторинг нагрузочного тестирования с InfluxDB и Grafana
Всевидящее око. Мониторинг нагрузочного тестирования с InfluxDB и GrafanaSQALab
 
Как сделать ваш JavaScript быстрее
Как сделать ваш JavaScript быстрееКак сделать ваш JavaScript быстрее
Как сделать ваш JavaScript быстрееRoman Dvornov
 
Ядро автоматизации под микро-сервисную архитектуру
Ядро автоматизации под микро-сервисную архитектуруЯдро автоматизации под микро-сервисную архитектуру
Ядро автоматизации под микро-сервисную архитектуруSQALab
 
Micro orm для жизни. Кожевников Дмитрий D2D Just.NET
Micro orm для жизни. Кожевников Дмитрий D2D Just.NETMicro orm для жизни. Кожевников Дмитрий D2D Just.NET
Micro orm для жизни. Кожевников Дмитрий D2D Just.NETDev2Dev
 
Ангелы и демоны многопоточного программирования / Алексей Федоров (Одноклассн...
Ангелы и демоны многопоточного программирования / Алексей Федоров (Одноклассн...Ангелы и демоны многопоточного программирования / Алексей Федоров (Одноклассн...
Ангелы и демоны многопоточного программирования / Алексей Федоров (Одноклассн...Ontico
 
Практика Lock-free. RealTime-сервер
Практика Lock-free. RealTime-серверПрактика Lock-free. RealTime-сервер
Практика Lock-free. RealTime-серверPlatonov Sergey
 

What's hot (20)

Производительность open source решений
Производительность open source решенийПроизводительность open source решений
Производительность open source решений
 
Быстрое построение backendов c помощью реактивных потоков
Быстрое построение backendов c помощью реактивных потоковБыстрое построение backendов c помощью реактивных потоков
Быстрое построение backendов c помощью реактивных потоков
 
Zabbix 3.4 - простая непростая дружба с сообществом / Алексей Владышев (Zabbix)
Zabbix 3.4 - простая непростая дружба с сообществом / Алексей Владышев (Zabbix)Zabbix 3.4 - простая непростая дружба с сообществом / Алексей Владышев (Zabbix)
Zabbix 3.4 - простая непростая дружба с сообществом / Алексей Владышев (Zabbix)
 
Организация процесса регулярной обработки больших объемов данных
Организация процесса регулярной обработки больших объемов данныхОрганизация процесса регулярной обработки больших объемов данных
Организация процесса регулярной обработки больших объемов данных
 
Kubernetes
KubernetesKubernetes
Kubernetes
 
Реактивный двигатель вашего Android приложения
Реактивный двигатель вашего Android приложенияРеактивный двигатель вашего Android приложения
Реактивный двигатель вашего Android приложения
 
Deployment to production with an unexpected load
Deployment to production with an unexpected loadDeployment to production with an unexpected load
Deployment to production with an unexpected load
 
10M tests per day
10M tests per day10M tests per day
10M tests per day
 
Zabbix 3.2 - мониторинг качественно нового уровня / Алексей Владышев (Zabbix)
Zabbix 3.2 - мониторинг качественно нового уровня / Алексей Владышев (Zabbix)Zabbix 3.2 - мониторинг качественно нового уровня / Алексей Владышев (Zabbix)
Zabbix 3.2 - мониторинг качественно нового уровня / Алексей Владышев (Zabbix)
 
Selenium grid on-demand
Selenium grid on-demandSelenium grid on-demand
Selenium grid on-demand
 
Алексей Романчук «Реактивное программирование»
Алексей Романчук «Реактивное программирование»Алексей Романчук «Реактивное программирование»
Алексей Романчук «Реактивное программирование»
 
Сенцов Сергей "Приемы оптимизаций Desktop приложений"
Сенцов Сергей "Приемы оптимизаций Desktop приложений"Сенцов Сергей "Приемы оптимизаций Desktop приложений"
Сенцов Сергей "Приемы оптимизаций Desktop приложений"
 
Что нам стоит DAL построить? Акуляков Артём D2D Just.NET
Что нам стоит DAL построить? Акуляков Артём D2D Just.NETЧто нам стоит DAL построить? Акуляков Артём D2D Just.NET
Что нам стоит DAL построить? Акуляков Артём D2D Just.NET
 
Олег Миколайченко "Как перестать хранить секреты в git и начать использовать ...
Олег Миколайченко "Как перестать хранить секреты в git и начать использовать ...Олег Миколайченко "Как перестать хранить секреты в git и начать использовать ...
Олег Миколайченко "Как перестать хранить секреты в git и начать использовать ...
 
Всевидящее око. Мониторинг нагрузочного тестирования с InfluxDB и Grafana
Всевидящее око. Мониторинг нагрузочного тестирования с InfluxDB и GrafanaВсевидящее око. Мониторинг нагрузочного тестирования с InfluxDB и Grafana
Всевидящее око. Мониторинг нагрузочного тестирования с InfluxDB и Grafana
 
Как сделать ваш JavaScript быстрее
Как сделать ваш JavaScript быстрееКак сделать ваш JavaScript быстрее
Как сделать ваш JavaScript быстрее
 
Ядро автоматизации под микро-сервисную архитектуру
Ядро автоматизации под микро-сервисную архитектуруЯдро автоматизации под микро-сервисную архитектуру
Ядро автоматизации под микро-сервисную архитектуру
 
Micro orm для жизни. Кожевников Дмитрий D2D Just.NET
Micro orm для жизни. Кожевников Дмитрий D2D Just.NETMicro orm для жизни. Кожевников Дмитрий D2D Just.NET
Micro orm для жизни. Кожевников Дмитрий D2D Just.NET
 
Ангелы и демоны многопоточного программирования / Алексей Федоров (Одноклассн...
Ангелы и демоны многопоточного программирования / Алексей Федоров (Одноклассн...Ангелы и демоны многопоточного программирования / Алексей Федоров (Одноклассн...
Ангелы и демоны многопоточного программирования / Алексей Федоров (Одноклассн...
 
Практика Lock-free. RealTime-сервер
Практика Lock-free. RealTime-серверПрактика Lock-free. RealTime-сервер
Практика Lock-free. RealTime-сервер
 

Similar to Regular expressions

Баба-Яга против! — Роман Дворнов, Ostrovok.ru
Баба-Яга против! — Роман Дворнов, Ostrovok.ruБаба-Яга против! — Роман Дворнов, Ostrovok.ru
Баба-Яга против! — Роман Дворнов, Ostrovok.ruYandex
 
PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#
PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#
PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#Andrey Karpov
 
Инструментируй это
Инструментируй этоИнструментируй это
Инструментируй этоRoman Dvornov
 
Баба Яга против!
Баба Яга против!Баба Яга против!
Баба Яга против!Roman Dvornov
 
Поговорим про память
Поговорим про памятьПоговорим про память
Поговорим про памятьAndrey Akinshin
 
Building deployment pipeline - DevOps way
Building deployment pipeline - DevOps wayBuilding deployment pipeline - DevOps way
Building deployment pipeline - DevOps wayAndrey Rebrov
 
My talk on DevOps :) at Stachka 2017
My talk on DevOps :) at Stachka 2017My talk on DevOps :) at Stachka 2017
My talk on DevOps :) at Stachka 2017Alex Chistyakov
 
Easy authcache 2 кеширование для pro родионов игорь
Easy authcache 2   кеширование для pro родионов игорьEasy authcache 2   кеширование для pro родионов игорь
Easy authcache 2 кеширование для pro родионов игорьdrupalconf
 
How to cook a blockchain and not get burned
How to cook a blockchain and not get burned How to cook a blockchain and not get burned
How to cook a blockchain and not get burned Alexander Syrotenko
 
Easy authcache 2 кэширование для pro. Родионов Игорь
Easy authcache 2   кэширование для pro. Родионов ИгорьEasy authcache 2   кэширование для pro. Родионов Игорь
Easy authcache 2 кэширование для pro. Родионов ИгорьPVasili
 
Scala, SBT & Play! for Rapid Application Development
Scala, SBT & Play! for Rapid Application DevelopmentScala, SBT & Play! for Rapid Application Development
Scala, SBT & Play! for Rapid Application DevelopmentAnton Kirillov
 
Пайплайн машинного обучения на Apache Spark / Павел Клеменков (Rambler&Co)
Пайплайн машинного обучения на Apache Spark / Павел Клеменков (Rambler&Co)Пайплайн машинного обучения на Apache Spark / Павел Клеменков (Rambler&Co)
Пайплайн машинного обучения на Apache Spark / Павел Клеменков (Rambler&Co)Ontico
 
Принципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-StudioПринципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-StudioAndrey Karpov
 
Void safety on Kiev ALT.NET
Void safety on Kiev ALT.NETVoid safety on Kiev ALT.NET
Void safety on Kiev ALT.NETSergey Teplyakov
 
D2D Pizza JS Илья Беда "Куда мы все катимся?"
D2D Pizza JS Илья Беда "Куда мы все катимся?"D2D Pizza JS Илья Беда "Куда мы все катимся?"
D2D Pizza JS Илья Беда "Куда мы все катимся?"Dev2Dev
 
Эффективный C++
Эффективный C++Эффективный C++
Эффективный C++Andrey Karpov
 
Сравнение статического анализа общего назначения из Visual Studio 2010 и PVS-...
Сравнение статического анализа общего назначения из Visual Studio 2010 и PVS-...Сравнение статического анализа общего назначения из Visual Studio 2010 и PVS-...
Сравнение статического анализа общего назначения из Visual Studio 2010 и PVS-...Tatyanazaxarova
 
Opensource на .NET
Opensource на .NETOpensource на .NET
Opensource на .NETlugnsk
 
Groovy presentation on Exception #7 conference
Groovy presentation on Exception #7 conferenceGroovy presentation on Exception #7 conference
Groovy presentation on Exception #7 conferencevoituk
 
Алексей Федоров
Алексей ФедоровАлексей Федоров
Алексей ФедоровCodeFest
 

Similar to Regular expressions (20)

Баба-Яга против! — Роман Дворнов, Ostrovok.ru
Баба-Яга против! — Роман Дворнов, Ostrovok.ruБаба-Яга против! — Роман Дворнов, Ostrovok.ru
Баба-Яга против! — Роман Дворнов, Ostrovok.ru
 
PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#
PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#
PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#
 
Инструментируй это
Инструментируй этоИнструментируй это
Инструментируй это
 
Баба Яга против!
Баба Яга против!Баба Яга против!
Баба Яга против!
 
Поговорим про память
Поговорим про памятьПоговорим про память
Поговорим про память
 
Building deployment pipeline - DevOps way
Building deployment pipeline - DevOps wayBuilding deployment pipeline - DevOps way
Building deployment pipeline - DevOps way
 
My talk on DevOps :) at Stachka 2017
My talk on DevOps :) at Stachka 2017My talk on DevOps :) at Stachka 2017
My talk on DevOps :) at Stachka 2017
 
Easy authcache 2 кеширование для pro родионов игорь
Easy authcache 2   кеширование для pro родионов игорьEasy authcache 2   кеширование для pro родионов игорь
Easy authcache 2 кеширование для pro родионов игорь
 
How to cook a blockchain and not get burned
How to cook a blockchain and not get burned How to cook a blockchain and not get burned
How to cook a blockchain and not get burned
 
Easy authcache 2 кэширование для pro. Родионов Игорь
Easy authcache 2   кэширование для pro. Родионов ИгорьEasy authcache 2   кэширование для pro. Родионов Игорь
Easy authcache 2 кэширование для pro. Родионов Игорь
 
Scala, SBT & Play! for Rapid Application Development
Scala, SBT & Play! for Rapid Application DevelopmentScala, SBT & Play! for Rapid Application Development
Scala, SBT & Play! for Rapid Application Development
 
Пайплайн машинного обучения на Apache Spark / Павел Клеменков (Rambler&Co)
Пайплайн машинного обучения на Apache Spark / Павел Клеменков (Rambler&Co)Пайплайн машинного обучения на Apache Spark / Павел Клеменков (Rambler&Co)
Пайплайн машинного обучения на Apache Spark / Павел Клеменков (Rambler&Co)
 
Принципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-StudioПринципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-Studio
 
Void safety on Kiev ALT.NET
Void safety on Kiev ALT.NETVoid safety on Kiev ALT.NET
Void safety on Kiev ALT.NET
 
D2D Pizza JS Илья Беда "Куда мы все катимся?"
D2D Pizza JS Илья Беда "Куда мы все катимся?"D2D Pizza JS Илья Беда "Куда мы все катимся?"
D2D Pizza JS Илья Беда "Куда мы все катимся?"
 
Эффективный C++
Эффективный C++Эффективный C++
Эффективный C++
 
Сравнение статического анализа общего назначения из Visual Studio 2010 и PVS-...
Сравнение статического анализа общего назначения из Visual Studio 2010 и PVS-...Сравнение статического анализа общего назначения из Visual Studio 2010 и PVS-...
Сравнение статического анализа общего назначения из Visual Studio 2010 и PVS-...
 
Opensource на .NET
Opensource на .NETOpensource на .NET
Opensource на .NET
 
Groovy presentation on Exception #7 conference
Groovy presentation on Exception #7 conferenceGroovy presentation on Exception #7 conference
Groovy presentation on Exception #7 conference
 
Алексей Федоров
Алексей ФедоровАлексей Федоров
Алексей Федоров
 

Regular expressions

  • 1. © 2015 NetCracker Technology Corporation Confidential Выражаемся регулярно Владимир Ситников JPoint 2015
  • 2. 2© 2015 NetCracker Technology Corporation Confidential О себе • Владимир Ситников, @VladimirSitnikv • Инженер по производительности в NetCracker • 8 лет опыта с Java/SQL • Мои предложения принимались в j.l.String, j.u.c.CopyOnWriteArrayList, jmh
  • 3. 3© 2015 NetCracker Technology Corporation Confidential План •Небольшое введение •Разгоняем /.*/ и /.*?/ •Устраняем StackOverflowError •Regexp vs XPath •ANTLR, VTD-XML – не на этом докладе
  • 4. 4© 2015 NetCracker Technology Corporation Confidential Regexp he com̡e̶s, ̕h̵i s un̨ho͞ly radiańcé destro҉ying all enli̍̈́̂̈́̍̈́̂̈́ ghtenment, HTML tags lea͠ki̧n ͘g fr̶ǫm ̡yo ͟ur eye͢s̸ ̛l̕ik͏e liq uid pain, the song of re̸gular exp ression parsing will exti nguish the voices of mor tal man from the sp here I can see it can you see î̩́t̲́̋̀t̲́̋̀ it is beautiful t he final snuffing of the lie s of Man ALL IS LOS ͖̩͇̗̪́̏̈́ T ALL I S LOST the pon̷y he comes he c̶̮omes he comes the ich or permeates all MY FACE MY FACE ᵒh god no NO NOO̼O O NΘ stop the an *̶͑̾̾ g͇̫͛͆̾ͫ̑͆l ̲͖͉̗̩̳̟́̋̀̍ͫͥͨ e̠̅s ͎a̧͈͖r ̽̾̈́͒͑ e n ot rè ̑ͧ̌ aͨl ̘̝̙̃ͤ͂̾̆ ZA̡͊͠͝LGΌ IS ͮ̂҉̯͈͕̹̘̱ TO͇̹̺ͅƝ̴ȳ̳ TH̘Ë͖́̉ ͠P̯͍̭O̚N̐Y̡ H̡Ȩ̬̩̾͛ͪ̈́̀́͘ ̶ͮ̂҉̯͈͕̹̘̱̯͍̭C ͭ̏ͥ ̷̙̲̝͖̘̝̙ͮ̃ͤ͂̾̆͟ ͖̈́̉ OM̚ ͊̒ͪͩͬ̚ ̖̚͜E̴̟̟͙̞͌͝S̨ ̨͎̥̫͎̭ͯ̿̔̀ͅ
  • 5. 5© 2015 NetCracker Technology Corporation Confidential Случаи использования regexp • Анализ success/fail в логах, xml ответа • Поиск “<status>success</status>” • Засекречивание паролей при логировании • Замена “password=(.*)” на “password=****” • По неосторожности
  • 6. 6© 2015 NetCracker Technology Corporation Confidential Случаи использования regexp • Анализ success/fail в логах, xml ответа • Поиск “<status>success</status>” • Засекречивание паролей при логировании • Замена “password=(.*)” на “password=****” • По неосторожности (String.replaceAll и т.п.)
  • 7. 7© 2015 NetCracker Technology Corporation Confidential Две проблемы •У вас проблема, и вы собрались использовать регулярные выражения для её решения •Теперь у вас две проблемы
  • 8. 8© 2015 NetCracker Technology Corporation Confidential Ужасы нашего городка
  • 9. 9© 2015 NetCracker Technology Corporation Confidential Что не так с .* ? •Обычно, regexp библиотеки работают «методом перебора» •Если хвост «не подошёл», откатим попробуем Regexp ещё раз
  • 10. 10© 2015 NetCracker Technology Corporation Confidential /^.*ab$/.match("ab") |ab .*ab a|b .*ab ab| .*ab ab| .*ab a|b .*ab откатились a|b .*ab не помогло |ab .*ab откатились ab| .*ab Ура! .* – жадная конструкция. Ест как не в себя
  • 11. 11© 2015 NetCracker Technology Corporation Confidential Ленивые вычисления спешат на помощь •Ленивый вариант помогает в конкретном случае /^.*?abc$/.match("abc") •Но помогает далеко не всегда
  • 12. 12© 2015 NetCracker Technology Corporation Confidential /^.*?b$/.match("aaa") |aab .*?ab a|ab .*?ab a|ab .*?ab |aab .*?ab откатились a|ab .*?ab aa|b .*?ab aab| .*?ab Ура! .*? – ленивая конструкция
  • 13. 13© 2015 NetCracker Technology Corporation Confidential Ленивые вычисления и реальность •Если regexp не подходит к строке, то всё равно придётся рассмотреть все случаи •Был случай, что выражение вида <.*:item.*>(.*)</.*:item> работало 30 секунд на 100 КиБ строке
  • 14. 14© 2015 NetCracker Technology Corporation Confidential Ленивые вычисления и реальность <.*?:item.*?>(.*?)</.*?:item> Уже лучше, regexp engine всё равно будет откатываться при выполнении .*
  • 15. 15© 2015 NetCracker Technology Corporation Confidential Ужасы нашего городка
  • 16. 16© 2015 NetCracker Technology Corporation Confidential Ленивые вычисления и реальность <[^:>]*:item[^>]*>([^<]*)</... [^>] не выйдет за границы XML тэга, вариантов будет намного меньше, и работать будет гораздо быстрее
  • 17. 17© 2015 NetCracker Technology Corporation Confidential Сравним 3 варианта • <ROW>.*<ACCNT>.*</ACCNT>.*</ROW> • <ROW>.*?<ACCNT>.*?</ACCNT>.*?</ROW> • <ROW>.*?<ACCNT>[^<]*</ACCNT>.*?</ROW>
  • 18. 18© 2015 NetCracker Technology Corporation Confidential График скорости .*, .*?, [^>] 0 100 200 300 400 1 КиБ 2 КиБ 3 КиБ 4 КиБ Быстрее,оп/мс .* .*? [^>]*
  • 19. 19© 2015 NetCracker Technology Corporation Confidential График скорости .*, .*?, [^>], шаблон не найден 0 10 20 30 40 50 1 КиБ 2 КиБ 3 КиБ 4 КиБ Быстрее,оп/мс .* .*? [^>]* Поиск тормозил, т.к. шаблон не нашёлся
  • 20. 20© 2015 NetCracker Technology Corporation Confidential JPoint или Joker? Pattern.compile("(Joker|JPoint)+") • На строке "JokerJPoint…700раз…Joker" падает с ошибкой StackOverflowError • Как так?
  • 21. 21© 2015 NetCracker Technology Corporation Confidential JPoint или Joker? java.lang.StackOverflowError .regex.Pattern$BranchConn.match(Pattern.java:4568 .regex.Pattern$Slice.match(Pattern.java:3972) .regex.Pattern$Branch.match(Pattern.java:4604) .regex.Pattern$GroupHead.match(Pattern.java:4658) .regex.Pattern$Loop.match(Pattern.java:4785) .regex.Pattern$GroupTail.match(Pattern.java:4717) .regex.Pattern$BranchConn.match(Pattern.java:4568
  • 22. 22© 2015 NetCracker Technology Corporation Confidential JPoint или Joker? Pattern.compile("(Joker|JPoint)+?") • Добавим "?". Помогло? • Падать перестало, но теперь посещаем только первую конференцию из всех
  • 23. 23© 2015 NetCracker Technology Corporation Confidential Однажды в NetBeans NetBeans Bug 154894 - StackOverflowError at java.util.regex.Pattern$SliceI.match support/JavadocAndSourceRootDetection.java String whitespace = "…(?:[^*]|*[^/])*…"
  • 24. 24© 2015 NetCracker Technology Corporation Confidential JPoint или Joker? Pattern.compile("(Joker|JPoint)+") • Regexp engine оставляет шанс отката для проверки альтернативной ветки • В OpenJDK Pattern использует ООП java stack, при большой вложенности и получается StackOverflow
  • 25. 25© 2015 NetCracker Technology Corporation Confidential Можно ли избавиться от откатов? Без откатов крайне сложно (невозможно?) сделать
  • 26. 26© 2015 NetCracker Technology Corporation Confidential Можно ли избавиться от откатов? Без откатов крайне сложно (невозможно?) сделать back-references: (.*)1 aa, abab, abcabc, …
  • 27. 27© 2015 NetCracker Technology Corporation Confidential Как это выглядит в документации Greedy Reluctant Posessive Значение X? X?? X?+ X, один раз или ни единого X* X*? X*+ X, ноль или более раз X+ X+? X++ X, один или более раз X{n} X{n}? X{n}+ X, ровно n раз X{n,} X{n,}? X{n,}+ X, как минимум n раз X{n,m} X{n,m}? X{n,m}+ X, от n до m раз https://docs.oracle.com/javase/tutorial/essential/regex/quant.html
  • 28. 28© 2015 NetCracker Technology Corporation Confidential Чего-чего?
  • 29. 29© 2015 NetCracker Technology Corporation Confidential А на это мало кто обращает внимание Greedy Reluctant Posessive Значение X? X?? X?+ X, один раз или ни единого X* X*? X*+ X, ноль или более раз X+ X+? X++ X, один или более раз
  • 30. 30© 2015 NetCracker Technology Corporation Confidential С++ спешит на помощь Pattern.compile("(Joker|JPoint)++") • ++ и *+ отключает откаты, и это как раз то, что нужно
  • 31. 31© 2015 NetCracker Technology Corporation Confidential «Мне повезёт» Pattern.compile("(?>Joker|JPoint)+") ?> – режим, при котором все откаты внутри скобок «забываются». Первый совпавший вариант принимается как окончательный
  • 32. 32© 2015 NetCracker Technology Corporation Confidential График скорости .*, .*, [^>], шаблон не найден 0 20 40 60 80 100 1 КиБ 2 КиБ 3 КиБ 4 КиБ Быстрее,оп/мс .* .*? [^>]* (?> <ROW>(?>.*?<RSACCTNMBR>) (?>[^<]*</RSACCTNMBR>)…
  • 33. 33© 2015 NetCracker Technology Corporation Confidential /(?>ab|a)b/.match("a") |ab (?>ab|a)b a|b (?>ab|a)b ab| (?>ab|a)b ab| (?>ab|a)b ab| (?>ab|a)b Шаблон не найден (?>ab|a) не будет проверять второй вариант
  • 34. 34© 2015 NetCracker Technology Corporation Confidential А давайте ускорим String? • String.format("...") использует java.util.regex.Pattern для разбора формата formatSpecifier = "%(d+$)?([-#+ 0,(<]*)?(d+)?(.d+)?([tT])?([a- zA-Z%])";
  • 35. 35© 2015 NetCracker Technology Corporation Confidential Откуда взять тестовые данные? Возьмём шаблон из самого JMH: (min, avg, max) = (%s, %s, %s), stdev = %s%n CI (99.9%%): [%s, %s] (assumes normal distribution)
  • 36. 36© 2015 NetCracker Technology Corporation Confidential А давайте ускорим String? formatSpecifier = "%(d+$)?([-#+ 0,(<]*)?(d+)?(.d+)?([tT])?([a- zA-Z%])"; fastSpecifier = "%(d++$)?+([-#+ 0,(<]+)?+(d++)?+(.d++)?+([tT])?+([a-zA- Z%])";
  • 37. 37© 2015 NetCracker Technology Corporation Confidential Бесплатный сыр Benchmark Cnt Score Error Units jdk18u45 60 1,067 ± 0,025 us/op optimized 60 0,917 ± 0,021 us/op
  • 38. 38© 2015 NetCracker Technology Corporation Confidential NetBeans, NetBeans (?>[^*]|*[^/]) Работает?
  • 39. 39© 2015 NetCracker Technology Corporation Confidential NetBeans, NetBeans (?>[^*]|*[^/]) StackOverflow не бросит, а на /***/ не сработает
  • 40. 40© 2015 NetCracker Technology Corporation Confidential NetBeans, NetBeans (?>[^*]|*(?!/)) Вот это уже сработает! (?!/) – negative lookahead
  • 41. 41© 2015 NetCracker Technology Corporation Confidential Признаки плохого регулярного выражения • Неспецифичные символы • .* • Внутри группировок • Повторения: (a+)+, ([a-zA-Z]+)*= • Альтернативы с пересечениями: (a|aa)+, (a|a?)+
  • 42. 42© 2015 NetCracker Technology Corporation Confidential А можно ли совсем без откатов? Если отказаться от back-references, то есть быстрые алгоритмы Детерминированный конечный автомат для /(1|01*0)*/
  • 43. 43© 2015 NetCracker Technology Corporation Confidential Современные regexp библиотеки в java Название Год выпуска Алгоритм java.util.regex.Pattern 2015 backtrack com.basistech.tclre 2015 DFA org.jruby.joni (Nashorn) 2014 backtrack Apache Oro 2000 backtrack JRegex 2013 backtrack
  • 44. 44© 2015 NetCracker Technology Corporation Confidential Современные regexp библиотеки в смежных языках Название Версия Алгоритм Oracle 12с backtrack PostgreSQL 9.3 DFA MySQL 5.6 DFA JavaScript/Chrome 43 backtrack JavaScript/FireFox 48 backtrack Python/Ruby/Perl/PHP backtrack
  • 45. 45© 2015 NetCracker Technology Corporation Confidential Как проверить backtrack? /(x+x+)+y/.test("xxxxx…20 раз…xxx") Если regexp с откатами, то он будет очень долго подбирать x+
  • 46. 46© 2015 NetCracker Technology Corporation Confidential /(x+x+)+y/.test("xxxx…xxx") 0 500 1000 1500 2000 5 6 7 Быстрее,op/ms java joni tcl jregex
  • 47. 47© 2015 NetCracker Technology Corporation Confidential /(x+x+)+y/.test("xxxx…xxx") 50 1 112 4 1 1240 1185 1151 21 0.07 0.02 0 500 1000 1500 10 15 20 Быстрее,op/ms java joni tcl jregex
  • 48. 48© 2015 NetCracker Technology Corporation Confidential <ROW>(?>.*?<RSACCTNMBR>)(?>[^<]*</RSACCTNMBR>) 30 5 1 0.4 23 4 1 0.4 42 9 3 1 95 47 31 2426 26 25 25 0 20 40 60 80 100 1 КиБ 2 КиБ 3 КиБ 4 КиБ Быстрее,op/ms .* .*? [^>]* (?> tcl, [^>]*
  • 49. 49© 2015 NetCracker Technology Corporation Confidential
  • 50. 50© 2015 NetCracker Technology Corporation Confidential CPU vs memory • DFA подход потребляет больше памяти • Патчим jmh, и там появляется allocation profiler
  • 51. 51© 2015 NetCracker Technology Corporation Confidential CPU vs memory: <row>… 0.2 0.2 0.2 0.2 32 32 32 32 0 10 20 30 40 1 КиБ 2 КиБ 3 КиБ 4 КиБ Память,КиБ/op java tcl Pattern#matcher потребляет всего 200 байт
  • 52. 52© 2015 NetCracker Technology Corporation Confidential CPU vs memory: <row>… 0 0 0 0 32 32 32 32 0 10 20 30 40 1 КиБ 2 КиБ 3 КиБ 4 КиБ Память,КиБ/op java tcl При Matcher#reset память вообще отдыхает
  • 53. 53© 2015 NetCracker Technology Corporation Confidential j.l.r.Pattern • Поддерживает Unicode (java 1.7+) • Управляемый откат • Малое потребление памяти
  • 54. 54© 2015 NetCracker Technology Corporation Confidential org.jruby.Joni • Поддерживает Unicode • Управляемый откат • Может работать с byte[] в UTF-8 кодировке • Поддерживает Thread#interrupt() • Малое потребление памяти
  • 55. 55© 2015 NetCracker Technology Corporation Confidential Tcl-re • DFA алгоритм, стабильное время работы • Не самая быстрая на простых шаблонах • Большое потребление памяти
  • 56. 56© 2015 NetCracker Technology Corporation Confidential Они всё ещё разбирают XML regexp’ами
  • 57. 57© 2015 NetCracker Technology Corporation Confidential Сравним с XPath • Парсинг XML (20, 40, 60КиБ) • Поиск тэга по точному пути • Замена пароля звёздочками (поиск по имени атрибута)
  • 58. 58© 2015 NetCracker Technology Corporation Confidential XPath • Парсинг XML • Поиск тэга по точному пути • ICOMS/MAC00029/@ACNT • Замена пароля звёздочками (поиск по имени атрибута) • //self::node()[@__hPINNMBR]
  • 59. 59© 2015 NetCracker Technology Corporation Confidential Regexp • Парсинг XML • Поиск тэга по точному пути, все вхождения • <MAC00029(?:.(?! ACNT))*+ ACNTN="([^"]*+)" • Замена пароля звёздочками (поиск по имени атрибута, все вхождения) • __hPINNMBR="[^"]*+"
  • 60. 60© 2015 NetCracker Technology Corporation Confidential Тестовая среда • Java 1.8u45, JMH 1.9 • Встроенный XPath • newXPath().compile • xpath.evaluate(parsedXml, XPathConstants.NODESET) • Intel Core i7-4960HQ CPU @ 2.60GHz
  • 61. 61© 2015 NetCracker Technology Corporation Confidential CPU: XML vs Pattern 6 3 1 8 7 43 4 2 67 35 15 79 38 24 0 20 40 60 80 100 20 КиБ 40 КиБ 60 КиБ Быстрее,оп/мс xmlParse xpExact xpSearch reExact reSearch j.u.r.Pattern
  • 62. 62© 2015 NetCracker Technology Corporation Confidential Heap: XML vs Pattern 86 167 266 299 310 358 500 319 370 0.2 0.2 0.20.2 0.2 0.2 0 200 400 600 20 КиБ 40 КиБ 60 КиБ Память,КиБ/oп xmlParse xpExact xpSearch reExact reSearch
  • 63. 63© 2015 NetCracker Technology Corporation Confidential Полмегабайта на xpath • Где моя память, чувак?! .jvmArgs("-XX:+UnlockCommercialFeatures", "-XX:+FlightRecorder", "-XX:StartFlightRecording=duration=60s," + "settings=profile," + "filename=xpathExact_60k.jfr")
  • 64. 64© 2015 NetCracker Technology Corporation Confidential JFR показывает кто виноват Java FlightRecorder показывает, что виноват XPathContext
  • 65. 65© 2015 NetCracker Technology Corporation Confidential One way ticket, one way ticket, … JDK-6344064 Potential XPath performance issue in "new XPathContext()". Fresh XPathContext is created for each call to evaluate(). However, the way the API is set up now, it is difficult not to do this. I'm assuming that the use case is having a W3C DOM and evaluating multiple XPath expressions on it.
  • 66. 66© 2015 NetCracker Technology Corporation Confidential Заключение • (?>…), ++, *+, ?+ отключают backtracking, что сильно ускоряет regexp • В простых случаях java.util работает быстро • Точный XPath работает быстрее Pattern, но аллоцирует уйму памяти
  • 67. © 2015 NetCracker Technology Corporation Confidential Вопросы? Владимир Ситников, JPoint 2015