I stumbled upon that performance test, saying that RegExps in JavaScript are not necessarily slow: http://jsperf.com/regexp-indexof-perf
There's one thing i didn't get though: two cases involve something that i believed to be exactly the same:
RegExp('(?:^| )foo(?: |$)').test(node.className);
And
/(?:^| )foo(?: |$)/.test(node.className);
In my mind, those two lines were exactly the same, the second one being some kind of shorthand to create a RegExp object. Still, it's twice faster than the first.
Those cases are called "dynamic regexp" and "inline regexp".
Could someone help me understand the difference (and the performance gap) between these two?
A regular expression (also called regex for short) is a fast way to work with strings of text. By formulating a regular expression with a special syntax, you can: search for text in a string.
In JavaScript, regular expressions are often used with the two string methods: search() and replace() . The search() method uses an expression to search for a match, and returns the position of the match. The replace() method returns a modified string where the pattern is replaced.
For a global, case-insensitive search, use the "i" modifier together with the g modifier.
RegExp Object A regular expression is a pattern of characters. The pattern is used to do pattern-matching "search-and-replace" functions on text. In JavaScript, a RegExp Object is a pattern with Properties and Methods.
Nowadays, answers given here are not entirely complete/correct.
Starting from ES5, the literal syntax behavior is the same as RegExp()
syntax regarding object creation: both of them creates a new RegExp object every time code path hits an expression in which they are taking part.
Therefore, the only difference between them now is how often that regexp is compiled:
RegExp()
syntax - every time new object gets createdSee, for instance, Stoyan Stefanov's JavaScript Patterns book:
Another distinction between the regular expression literal and the constructor is that the literal creates an object only once during parse time. If you create the same regular expression in a loop, the previously created object will be returned with all its properties (such as lastIndex) already set from the first time. Consider the following example as an illustration of how the same object is returned twice.
function getRE() { var re = /[a-z]/; re.foo = "bar"; return re; } var reg = getRE(), re2 = getRE(); console.log(reg === re2); // true reg.foo = "baz"; console.log(re2.foo); // "baz"
This behavior has changed in ES5 and the literal also creates new objects. The behavior has also been corrected in many browser environments, so it’s not to be relied on.
If you run this sample in all modern browsers or NodeJS, you get the following instead:
false bar
Meaning that every time you're calling the getRE()
function, a new RegExp
object is created even with literal syntax approach.
The above not only explains why you shouldn't use the RegExp()
for immutable regexps (it's very well known performance issue today), but also explains:
(I am more surprised that inlineRegExp and storedRegExp have different results.)
The storedRegExp
is about 5 - 20% percent faster across browsers than inlineRegExp
because there is no overhead of creating (and garbage collecting) a new RegExp
object every time.
Conclusion:
Always create your immutable regexps with literal syntax and cache it if it's to be re-used. In other words, don't rely on that difference in behavior in envs below ES5, and continue caching appropriately in envs above.
Why literal syntax? It has some advantages comparing to constructor syntax:
- It is shorter and doesn’t force you to think in terms of class-like constructors.
- When using the
RegExp()
constructor, you also need to escape quotes and double-escape backslashes. It makes regular expressions that are hard to read and understand by their nature even more harder.
(Free citation from the same Stoyan Stefanov's JavaScript Patterns book).
Hence, it's always a good idea to stick with the literal syntax, unless your regexp isn't known at the compile time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With