gpt4 book ai didi

javascript - JavaScript 中的动态与内联 RegExp 性能

转载 作者:IT王子 更新时间:2023-10-29 03:20:30 25 4
gpt4 key购买 nike

我偶然发现了那个性能测试,说 JavaScript 中的正则表达式不一定很慢:http://jsperf.com/regexp-indexof-perf

有一件事我没有明白:两个案例涉及的东西我认为是完全一样的:

RegExp('(?:^| )foo(?: |$)').test(node.className);

/(?:^| )foo(?: |$)/.test(node.className);

在我看来,这两行完全相同,第二行是创建 RegExp 对象的某种速记。尽管如此,它还是比第一个快两倍

这些情况称为“动态正则表达式”和“内联正则表达式”。

谁能帮我理解这两者之间的差异(和性能差距)?

最佳答案

现在,这里给出的答案并不完全/正确。

从 ES5 开始,字面量语法行为与 RegExp() 对象创建语法相同:两者都在每次代码路径命中时创建一个新的 RegExp 对象他们正在参与的表达方式。

因此,现在它们之间的唯一区别是编译正则表达式的频率:

  • 使用文字语法 - 一次在初始代码解析期间和编译
  • 使用 RegExp() 语法 - 每次都会创建新对象

参见,例如,Stoyan Stefanov's JavaScript Patterns书:

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.

如果您在所有现代浏览器或 NodeJS 中运行此示例,您将获得以下内容:

false
bar

这意味着每次调用 getRE() 函数时,都会创建一个新的 RegExp 对象,即使使用字面语法方法也是如此 .

以上不仅解释了为什么不应该将 RegExp() 用于不可变的正则表达式(这是当今众所周知的性能问题),还解释了:

(I am more surprised that inlineRegExp and storedRegExp have different results.)

storedRegExp 在浏览器中比 inlineRegExp 快大约 5% - 20%,因为没有创建(和垃圾收集)新 RegExp< 的开销 对象每次。

结论:
始终使用文字语法创建不可变的正则表达式,并在要重复使用时缓存它。换句话说,不要依赖低于 ES5 的环境中的行为差异,并继续在高于 ES5 的环境中适本地缓存。

为什么是字面语法?与构造函数语法相比,它有一些优点:

  1. It is shorter and doesn’t force you to think in terms of class-like constructors.
  2. 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.

(同一本书的免费引用 Stoyan Stefanov's JavaScript Patterns)。
因此,坚持使用文字语法始终是个好主意,除非您的正则表达式在编译时未知。

关于javascript - JavaScript 中的动态与内联 RegExp 性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9750338/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com