Повторяю еще раз с уточнением: без JIT-компиляции регулярные выражения Java вдвое медленнее Python.
Меня поражает свойство некоторых людей спорить до упора и наверно еще свято верить в свою правоту.
Ваши аргументы в этом споре:
Надо задействовать JIT- так будет быстрее, чем в Python
На крайний случай можно задействовать JNI
Ой, да и вообще, регулярные выражения мало кто использует, а если и использует, то непременно в большом цикле с предварительным прогревом
Если производительность не просела именно от регулярных выражений- зачем вообще говорить о их производительности
Зачем Вам это нужно?
Вы фанатик Java?
Я Вам привел примитивный тест, который Java проваливает в 2 раза. Могу поэкспериментировать и найти узкие места реализации движка из-за которых Питон обгонит Java в 3 и более раз, но зачем мне это? Доказать фанатикам что-либо нереально- они не видят очевидного.
Спор ради спора- это Ваша цель?
Я знаю с какой скоростью все это работает из коробки и знаю как все это можно ускорить, поэтому делаю только те заявления, которые мной лично проверены.
Когда нужно много регулярных выражений- использую PHP. В нем можно использовать весь синтаксис PCRE.
public static void main (String[] args) throws java.lang.Exception
{
Pattern pat = Pattern.compile( ".*a.*?b.*" );
boolean b;
String text = " a b ";
Matcher m;
for ( int i=0; i<5000000; i++ ) {
m = pat.matcher( ""+i );
}
long t1 = System.currentTimeMillis();
for ( int i=0; i<500000; i++ ) {
m = pat.matcher( text+i);
b = m.matches();
}
long t2 = System.currentTimeMillis();
System.out.print( t2 - t1 );
}
А если хотите сравнить результаты после JIT-компиляции, то давайте сравним с PHP, а не Python- так будет честно.
Когда сработала JIT-компиляция на этот кусок бесполезного цикла, то уже нельзя сравнивать результат с результатом Python.
На сим прекращаю спор с Вами. Вы не понимаете сути проблемы, к сожалению.
Никто никогда не будет применять одно и тоже регулярное выражение к одному и тому же тексту 500000 раз и ждать когда прогреется JVM, чтобы запустить JIT-компиляцию.
Ну а тем, кто ставит минусики этому комментарию рекомендую произвести реальные тесты производительности регулярных выражений в Java в сравнении с другими языками. Можете их даже взять в комментарии чуть выше.
Этот комментарий был не вбросом ради холивара. Для меня очень важны регулярные выражения и их производительность. В Java они меня очень расстраивают.
Python3 http://ideone.com/3w5A7Z
Java http://ideone.com/dwqy55
На IDEone разница 3 раза, на моей локальной машине (Python35 Java8) разница в 2 раза.
Запустите тесты на своей машине, если не сложно. Может быть в Вашей реализации Python он будет соизмерим по скорости с Java.
Несмотря на отсутствие в GooglePlay\AppStore у Pokemon Go не менее 2млн установок по России (самые минимальные оценки из статей СМИ). О таком количестве установок мечтают опубликованные приложения.
В организации, где я работаю (50 человек), минимум 4 активно играют в Покемонов (возможно больше, но я их еще не видел).
На два портала рядом с работой кто-то постоянно активирует донатные моды.
О каком "перегорании" Вы говорите?
Это только кажется проблемой. На самом деле все решается за день-два.
Нужно создать вопрос на «Мета» с просьбой создать новую метку.
Объяснить, что Вы хотите создать ее для документирования своего фреймворка.
Очень быстро найдутся участники, которые проголосуют за создание метки.
Такие преценденты уже были. Человек с маленькой репутацией переносил с домашней страницы своей библиотеки мануал по ней в формате QA.
Все решаемо. На СО сидят люди, а не роботы.
Когда новый сайт сети стэкэксчендж проходит бета-тестирование, то рамки репутации сильно занижены. С выходом из беты будет повышена репутация, необходимая для редактирования документации, и, скорее всего, нужно будет иметь знак по этой метке.
Вы излишне все усложнили, поэтому получили трудночитаемое регулярное выражение и сложный код.
Все гораздо проще. Для того, чтобы удалить все комментарии надо найти альтернативы:
("(?:\\[\s\S]|[^"])*") что означает- внутри кавычек есть: что-то экранированное, или что угодно, кроме кавычки
((?:\/\/|#)[^\n]*) что означает — однострочный комментарий
(\/\*[\s\S]*?\*\/) что означает многострочный комментарий
и оставить от него только $1 в строке замены. https://regex101.com/r/wD0gQ6/1
Почему это будет работать вообще и работать корректно? Движок регексов будет последовательно применять эти альтернативы к каждой позиции текста, встретив кавычку применит первую альтернативу (если JSON валиден), встретив начало комментариев применит другие альтернативы и при этом захватит всю эту составную часть целиком, то есть внутри комментария или кавычек может быть что угодно- ложного срабатывания не будет.
С заменой значения по ключу тоже все относительно просто при таком подходе, но сначала надо изменить регулярное выражение:
Помимо чего-то внутри кавычек в тексте могут быть числа, true, false, null (массивы и объекты не рассматриваю, потому что в топике они тоже не учитываются)
Именованный ключ нам может встретиться после символов { и , — необходимо установить флаг, что когда встретится что-то в кавычках — это будет ключ.
При такой реализации возможно добавить в функцию replacer флаги глубины вложенности, флаги начала массива или объекта и корректно их обрабатывать, но это не оговорено в топике, поэтому не буду это делать.
P.S. Не сочтите меня снобом, пожалуйста. Просто начал писать комментарий про неоправданно сложное регулярное выражение там где все решается значительно проще, но заодно накидал код замены, поэтому такой большой комментарий вышел.
И у Вас еще одно заблуждение.
Посмотрел последнюю ревизию регулярки- там Вы считаете, что в комментариях (?# / ) может быть ограничитель.
Это неверное мнение. Даже в комментариях ограничитель надо экранировать: http://ideone.com/rhVCb7
Вы излишне все усложнили в итоге получили нечитаемое выражение и ложные срабатывания вроде https://regex101.com/r/mS2vZ8/2
На самом деле регулярное выражение, которое решит данную задачу будет не особо трэшевым.
Я сохранил Ваши определения ограничителей и флагов, но само выражение гораздо проще: https://regex101.com/r/mS2vZ8/3
Посмотрите этот тест: https://jsfiddle.net/4x5v6yk7/4/
Решил исключить возможность кэширования регулярных выражений (ведь все-таки к одной строке всегда применяли) и получил интересный результат- теперь даже в FF 47.0 тест 2 в 1,5 раза быстрее теста 3, в хроме в 2,5 раза
Чем больше длина строки тем сильнее регулярные выражения будут обгонять "чистую" реализацию https://jsfiddle.net/4x5v6yk7/5/
Еще один плюс в пользу регулярных выражений.
Повторяю еще раз с уточнением: без JIT-компиляции регулярные выражения Java вдвое медленнее Python.
Меня поражает свойство некоторых людей спорить до упора и наверно еще свято верить в свою правоту.
Ваши аргументы в этом споре:
Зачем Вам это нужно?
Вы фанатик Java?
Я Вам привел примитивный тест, который Java проваливает в 2 раза. Могу поэкспериментировать и найти узкие места реализации движка из-за которых Питон обгонит Java в 3 и более раз, но зачем мне это? Доказать фанатикам что-либо нереально- они не видят очевидного.
Спор ради спора- это Ваша цель?
Я знаю с какой скоростью все это работает из коробки и знаю как все это можно ускорить, поэтому делаю только те заявления, которые мной лично проверены.
Когда нужно много регулярных выражений- использую PHP. В нем можно использовать весь синтаксис PCRE.
Прогрейте так:
А если хотите сравнить результаты после JIT-компиляции, то давайте сравним с PHP, а не Python- так будет честно.
Когда сработала JIT-компиляция на этот кусок бесполезного цикла, то уже нельзя сравнивать результат с результатом Python.
На сим прекращаю спор с Вами. Вы не понимаете сути проблемы, к сожалению.
Никто никогда не будет применять одно и тоже регулярное выражение к одному и тому же тексту 500000 раз и ждать когда прогреется JVM, чтобы запустить JIT-компиляцию.
Ну а тем, кто ставит минусики этому комментарию рекомендую произвести реальные тесты производительности регулярных выражений в Java в сравнении с другими языками. Можете их даже взять в комментарии чуть выше.
Этот комментарий был не вбросом ради холивара. Для меня очень важны регулярные выражения и их производительность. В Java они меня очень расстраивают.
Как я понимаю- для избежания путаницы нужно писать не CPython, а Python ;)
Python3
http://ideone.com/3w5A7Z
Java
http://ideone.com/dwqy55
На IDEone разница 3 раза, на моей локальной машине (Python35 Java8) разница в 2 раза.
Запустите тесты на своей машине, если не сложно. Может быть в Вашей реализации Python он будет соизмерим по скорости с Java.
Очень-очень это в 2-3 раза медленнее, чем PHP, Python (даже не CPython), NodeJS.
Несмотря на отсутствие в GooglePlay\AppStore у Pokemon Go не менее 2млн установок по России (самые минимальные оценки из статей СМИ). О таком количестве установок мечтают опубликованные приложения.
В организации, где я работаю (50 человек), минимум 4 активно играют в Покемонов (возможно больше, но я их еще не видел).
На два портала рядом с работой кто-то постоянно активирует донатные моды.
О каком "перегорании" Вы говорите?
А очень-очень медленные регулярные выражения в Java будут исправлены когда-нибудь?
Это только кажется проблемой. На самом деле все решается за день-два.
Нужно создать вопрос на «Мета» с просьбой создать новую метку.
Объяснить, что Вы хотите создать ее для документирования своего фреймворка.
Очень быстро найдутся участники, которые проголосуют за создание метки.
Такие преценденты уже были. Человек с маленькой репутацией переносил с домашней страницы своей библиотеки мануал по ней в формате QA.
Все решаемо. На СО сидят люди, а не роботы.
Когда новый сайт сети стэкэксчендж проходит бета-тестирование, то рамки репутации сильно занижены. С выходом из беты будет повышена репутация, необходимая для редактирования документации, и, скорее всего, нужно будет иметь знак по этой метке.
Вы излишне все усложнили, поэтому получили трудночитаемое регулярное выражение и сложный код.
Все гораздо проще. Для того, чтобы удалить все комментарии надо найти альтернативы:
("(?:\\[\s\S]|[^"])*")что означает- внутри кавычек есть: что-то экранированное, или что угодно, кроме кавычки((?:\/\/|#)[^\n]*)что означает — однострочный комментарий(\/\*[\s\S]*?\*\/)что означает многострочный комментарийРезультирующее выражение:
и оставить от него только
$1в строке замены.https://regex101.com/r/wD0gQ6/1
Почему это будет работать вообще и работать корректно? Движок регексов будет последовательно применять эти альтернативы к каждой позиции текста, встретив кавычку применит первую альтернативу (если JSON валиден), встретив начало комментариев применит другие альтернативы и при этом захватит всю эту составную часть целиком, то есть внутри комментария или кавычек может быть что угодно- ложного срабатывания не будет.
С заменой значения по ключу тоже все относительно просто при таком подходе, но сначала надо изменить регулярное выражение:
true,false,null(массивы и объекты не рассматриваю, потому что в топике они тоже не учитываются){и,— необходимо установить флаг, что когда встретится что-то в кавычках — это будет ключ.Результирующее регулярное выражение:
Весь код помещается в несколько строк:
https://jsfiddle.net/hb5LzuL7/
При такой реализации возможно добавить в функцию
replacerфлаги глубины вложенности, флаги начала массива или объекта и корректно их обрабатывать, но это не оговорено в топике, поэтому не буду это делать.P.S. Не сочтите меня снобом, пожалуйста. Просто начал писать комментарий про неоправданно сложное регулярное выражение там где все решается значительно проще, но заодно накидал код замены, поэтому такой большой комментарий вышел.
В разделе регулярные выражения указаны устаревшие малофункциональные сайты. Рекомендую обновить ссылки на достойные сервисы:
http://regex101.com PCRE (PHP), JavaScript, Python;
http://debuggex.com PCRE, JavaScript, Python (создает графическую иллюстрацию);
http://refiddle.com JavaScript, Rubi, .NET;
http://regexplanet.com Go, Haskell, Java, JavaScript, .NET, Perl, PHP, Python, Rubi, Tcl, XRegExp.
Попробуйте
/(?:)/uпо моим замерам оно быстрее Вашего на 5% в среднем.Нельзя найти такие решения. В данной задаче регулярное выражение всегда будет быстрее «чистой» реализации, если не использовать оператор
...Если будете добавлять, то эту версию- https://regex101.com/r/mS2vZ8/4 немного лучше производительность.
Ну конечно добавляйте.
И у Вас еще одно заблуждение.
Посмотрел последнюю ревизию регулярки- там Вы считаете, что в комментариях
(?# / )может быть ограничитель.Это неверное мнение. Даже в комментариях ограничитель надо экранировать:
http://ideone.com/rhVCb7
Вы излишне все усложнили в итоге получили нечитаемое выражение и ложные срабатывания вроде https://regex101.com/r/mS2vZ8/2
На самом деле регулярное выражение, которое решит данную задачу будет не особо трэшевым.
Я сохранил Ваши определения ограничителей и флагов, но само выражение гораздо проще:
https://regex101.com/r/mS2vZ8/3
Посмотрите этот тест: https://jsfiddle.net/4x5v6yk7/4/
Решил исключить возможность кэширования регулярных выражений (ведь все-таки к одной строке всегда применяли) и получил интересный результат- теперь даже в FF 47.0 тест 2 в 1,5 раза быстрее теста 3, в хроме в 2,5 раза
Чем больше длина строки тем сильнее регулярные выражения будут обгонять "чистую" реализацию
https://jsfiddle.net/4x5v6yk7/5/
Еще один плюс в пользу регулярных выражений.