Быстрый trim для JavaScript
Самый быстрый trim на JavaScript выглядит странно:
function trim12 (str) {
var str = str.replace(/^\s\s*/, ''),
ws = /\s/,
i = str.length;
while (ws.test(str.charAt(--i)));
return str.slice(0, i + 1);
}
Код взят из блога Flagrant Badassery. Цикл с регуляркой быстрее, чем простое регулярное выражение /\s+$/, а кроме того, \s\s* быстрее, чем \s+? OMG!
Регулярные выражения — это же не магия, а конечные автоматы. ^_^
Это вполне понятно — цикл делает только то, что надо — сравнивает с «пробельным классом символов» по одному символы, начиная с конца строки, пока они есть.
А «простое регулярное выражение» начинает сопоставляться с каждого «пробельного» символа, начиная с начала строки, потом обламывается, не обнаружив конца строки после пробелов (если их было несколько подряд — то всё равно пытается проделать то же самое начиная со второго из них, и т. д...).
Это не столь очевидно, правда, напоминает фридловскую «развёртку регекспа», но сейчас не помню, почему она эффективнее.
(И не понимаю, почему оно эффективнее _здесь_. -_-’)
«Простое» регулярное выражение спотыкается на каждом пробеле, пока дойдёт до конца строки; приведённый код сразу идёт в конец и ищет пробелы перед ним.
Комментарий для razetdinov.ya.ru:
Движки регулярок сильно оптимизируются. \s+$ вполне можно соптимизировать как «начать цикл с конца, если не пробел, остановиться». Я не смотрел в код, но даже не сомневаюсь, что libprce именно так и делает.
Комментарий для baka.name:
Я понимаю, что это не магия. Но я ожидал от движков регулярных выражений в JS большей оптимизированности. \s\s* просто обнажает недостатки этих движков.
Комментарий для razetdinov.ya.ru:
«Если не пробел» читать как «если не пробельный символ».
Комментарий для Евгения Степанищева:
http://pcre.org/pcre.txt
“Consider a simple pattern such as ‘abcd$’ when applied to a long string that does not match. Because matching proceeds from left to right, PCRE will look for each «a» in the subject and then see if what follows matches the rest of the pattern.”
Комментарий для razetdinov.ya.ru:
Как всё плохо-то :(
У браузеров разные движки, вроде бы? Насколько я знаю, Firefox и Chrome используют какие-то новые разработки, компилируемый JS.
Комментарий для realsonic.moikrug.ru:
Разные, конечно. Но оптимизация regexp, видимо, находится в удручающем состоянии у всех.
Суть проблемы в том, что для JavaScript строка одним куском — по сути join массива.
Соответственно — методы массива на большом массиве работают быстрее, чем литеральная его обработка после join.
Ведь str.charAt(--i)=str[--i]
Так и получается, когда «все есть объект».
Т. е. смысл в том, что сама по себе задача решается для «сферического коня в вакууме».
Я на стопяцот процентов уверен, что «откуси» он достаточный кусок СНАЧАЛА и с КОНЦА и обработай оба одной и той же регуляркой /^\s+|\s+$/ а потом слепи он это обратно — будет не медленнее его конечного варианта. Но так же извратно по сути. :)
Регулярные выражения javascript
http://forjoomla.ru/regulyarnie-virajeniya-javascript.html
Комментарий для rews:
Простите, но чем эта статья лучше 100500 других куцых статей на ту же тему?