【问题标题】:When are JavaScript regular expression literals compiled何时编译 JavaScript 正则表达式文字
【发布时间】:2014-02-14 06:49:45
【问题描述】:

根据MDN's RegExp Guide,正则表达式文字会被编译,而通过调用构造函数创建的 RegExp 对象则不会。

我现在的问题是,编译什么时候进行?由于文字具有独特的语法,因此在解析期间它被标识为正则表达式。这样就可以编译一次并在每次评估时重用结果,从而导致两个示例具有(几乎)相同的速度。

var str = "Hello World";

// Example 1
var regExp1 = /[aeiou]+/gi;
for(var i = 0; i < 1000; ++i)
    regExp1.exec(str);

// Example 2
for(var j = 0; j < 1000; ++j)
    /[aeiou]+/gi.exec(str);

任何想法是否被任何 JavaScript 引擎在实践中使用?

【问题讨论】:

标签: javascript regex performance compilation


【解决方案1】:

MDN docs 明确指出:

文字符号在计算表达式时提供正则表达式的编译。

正则表达式对象的构造函数,例如new RegExp("ab+c"),提供正则表达式的运行时编译

你做的测试不是很清楚。你在哪里衡量绩效?这就是我认为应该制作的方式:

start = new Date();
for(var j = 0; j < 1000000; ++j)
    /[aeiou]+/gi.exec(str);
console.log(new Date - start);

start = new Date();
regex = new RegExp("[aeiou]+", "gi");
for(var j = 0; j < 1000000; ++j)
    regex.exec(str);
console.log(new Date - start);

这会产生:

147
118

显然,在我的测试中,构造函数更快(Chrome)

在您的测试中,您根本没有测试构造函数。您只是将第一个测试中的文字分配给变量名。基本上测试是相同的。

【讨论】:

  • 因此,像一次性评估和通过解析器重用这样的优化不太可能实现,因为它违反了 MDN 的规范。
  • 另一方面,它似乎根本不需要。我用更复杂的表达式进行了测试,与匹配所需的时间相比,编译时间很短(至少对于 Firefox 29)。因此,如果正在使用许多正则表达式,可以通过在循环内指定正则表达式来使代码更具可读性。
  • 也应该测试在循环内调用构造函数。您无法创建完整的正则表达式对象,但您可以解析和编译正则表达式,而无需为运行时生成实际对象。这比不优化要快,但比第一次测试要慢。由于它是文字,因此编译后的版本是静态的。
  • MDN Guide 明确建议使用文字。 正则表达式文字在脚本加载时提供正则表达式的编译。当正则表达式保持不变时,使用它以获得更好的性能。它是什么?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-10
相关资源
最近更新 更多