У меня в Chrome крайней версии от 1.7 до 2 колеблется отношении времени теста 3 к тесту 2.
В этом нет ничего удивительного и неожиданного- такие результаты будут практически в любом языке, который не компилирует код или не имеет JIT-компиляции.
Конечно, все зависит от конкретных примеров регулярных выражений, но скорее всего большинство их будет быстрее их "чистой" реализации ввиду того, что обработка строки регулярным выражением в таких языках — всего один вызов нативной функции, который быстрее множества инструкций байт-кода.
Хочу извиниться- функция в тесте не оптимальна.
Тест с оптимальной реализацией: https://jsfiddle.net/yq9gh6mm/2/
В нем "чистая" реализация проигрывает уже всего в 2 раза.
А после компиляции NodeJS "чистая" реализация на 13% быстрее регулярки /[^a-z0-9]+/ig http://ideone.com/juoJQr
Регулярные выражения при работе со строками практически всегда быстрее простого кода в некомпилируемых языках (коим и является клиентский JavaScript).
Сделал небольшой тест: https://jsfiddle.net/yq9gh6mm/1/
Тестируется очистка строки от лишних символов регулярными выражениями /[^a-z0-9]/ig, /[^a-z0-9]+/ig и реализацией на чистом JS.
Реализация без регулярных выражений проигрывает почти в 4 раза по скорости второму регулярному выражению.
Использование регулярных выражений весьма оправдано, как минимум на стороне клиента.
Компиляция NodeJs немного исправит ситуацию и реализация на чистом JS почти догонит регулярные выражения, но не обгонит. Тот же самый тест на NodeJS: http://ideone.com/juoJQr
(?<=^|[^\x5c]|(?:^|[^\x5c])(?:\x5c{2})+)\x5b[^\x5d]+\x5d
полностью эквивалентно (?<=^|[^\x5c](?:\x5c{2})*)\x5b[^\x5d]+\x5d
Дело вкуса, конечно, но то, что Вы называете "избавление от ряби в глазах" еще сильнее усложняет восприятие регулярного выражения (как мне кажется) (?<=^|[^\\](?:\\{2})*)\[[^\]]+\]
выглядит привычно и читаемо. Хотя, если честно, сам иногда пишу в похожем варианте, когда слишком много экранированных символов в регулярном выражении: var re = "(?<=^|[^\\](?:\\{2})*)LT[^GT]+GT".replace( /LT/g, "\\[" ).replace( /GT/g, "\\]" );
В регулярном выражении могут быть одиночные символы, символьные классы и метасимволы символьных классов. На этапе поиска вариантов не имеет значения, что они собой обозначают. Они считаются неделимыми «атомами».
Какие литералы они собой обозначают вычисляется при помощи функции char2set на последующих этапах, в частности при объединении «атомов».
Не помню, чтобы я употребил формулировку «несколько символов». Несомненно, что квантификатор * означает 0 или более вхождений.
http://ideone.com/Yo5iDE
Добавляем поддержку русского алфавита и забываем про то, что NodeJS обгонял по скорости регулярное выражение.
У меня в Chrome крайней версии от 1.7 до 2 колеблется отношении времени теста 3 к тесту 2.
В этом нет ничего удивительного и неожиданного- такие результаты будут практически в любом языке, который не компилирует код или не имеет JIT-компиляции.
Конечно, все зависит от конкретных примеров регулярных выражений, но скорее всего большинство их будет быстрее их "чистой" реализации ввиду того, что обработка строки регулярным выражением в таких языках — всего один вызов нативной функции, который быстрее множества инструкций байт-кода.
Хочу извиниться- функция в тесте не оптимальна.
Тест с оптимальной реализацией: https://jsfiddle.net/yq9gh6mm/2/
В нем "чистая" реализация проигрывает уже всего в 2 раза.
А после компиляции NodeJS "чистая" реализация на 13% быстрее регулярки
/[^a-z0-9]+/ighttp://ideone.com/juoJQr
Регулярные выражения при работе со строками практически всегда быстрее простого кода в некомпилируемых языках (коим и является клиентский JavaScript).
Сделал небольшой тест: https://jsfiddle.net/yq9gh6mm/1/
Тестируется очистка строки от лишних символов регулярными выражениями
/[^a-z0-9]/ig,/[^a-z0-9]+/igи реализацией на чистом JS.Реализация без регулярных выражений проигрывает почти в 4 раза по скорости второму регулярному выражению.
Использование регулярных выражений весьма оправдано, как минимум на стороне клиента.
Компиляция NodeJs немного исправит ситуацию и реализация на чистом JS почти догонит регулярные выражения, но не обгонит. Тот же самый тест на NodeJS: http://ideone.com/juoJQr
Вы усложнили выражение более, чем это требуется.
(?<=^|[^\x5c]|(?:^|[^\x5c])(?:\x5c{2})+)\x5b[^\x5d]+\x5dполностью эквивалентно
(?<=^|[^\x5c](?:\x5c{2})*)\x5b[^\x5d]+\x5d(?<=^|[^\\](?:\\{2})*)\[[^\]]+\]выглядит привычно и читаемо. Хотя, если честно, сам иногда пишу в похожем варианте, когда слишком много экранированных символов в регулярном выражении:
var re = "(?<=^|[^\\](?:\\{2})*)LT[^GT]+GT".replace( /LT/g, "\\[" ).replace( /GT/g, "\\]" );В регулярном выражении могут быть одиночные символы, символьные классы и метасимволы символьных классов. На этапе поиска вариантов не имеет значения, что они собой обозначают. Они считаются неделимыми «атомами».
Какие литералы они собой обозначают вычисляется при помощи функции
char2setна последующих этапах, в частности при объединении «атомов».Не помню, чтобы я употребил формулировку «несколько символов». Несомненно, что квантификатор
*означает 0 или более вхождений.