如何加速我的正则表达式?

5

我正在编写一个脚本,将所有内容的URL更改到新位置。

var regex = /.*cloudfront.net/
var pDistro = "newDistro.cloudfront.net/"

for(var i=0;i<strings.length;i++){
    strings[i] = strings[i].replace(regex,pDistro);
}

我正在对平均每个字符串大约140个字符的URL进行替换。它们遵循以下格式:https://[thing to replace].cloudfront.net/[something]/[something]/[something]。但是,这个操作非常缓慢,平均大小的数组处理需要大约4.5秒。为什么这么慢?如何让它更快?
如果这个问题更适合codereview堆栈交换或其他网站,请告诉我,我会将其移动到那里。
编辑:从我拉取的数据库中提取出来的数据看起来是140个字符。在拉取过程中,进行了一些虚拟化并将另外400个字符附加到字符串上,所以不奇怪正则表达式需要这么长时间。像其他人指出的那样,循环140个字符的字符串需要较少的时间。故事的道理是:“确保你拥有的数据符合你的期望”,“如果您的正则表达式花费太长时间,请使用较小的字符串和更具体的正则表达式(即无通配符)”。

4
什么是平均大小的数组? - dramzy
2
你能提供样例代码和数据来验证建议吗? - vinayakj
4
在Chrome的控制台上,对一个包含1000个长度超过120个字符的字符串数组执行此操作只需要几毫秒时间。尽管这些字符串是随机生成的,并且在“.cloudfront.net”之前有一些数字,但是无论字符串长什么样子,执行时间都不应该那么长。延迟可能来自其他地方吗? - dramzy
2
根据 OP 的说法,只有大约 10 个每个元素包含 140 个字符的东西,因此我的猜测是还有其他东西也在消耗时间。 - vinayakj
1
@vinayakj,你是对的。我的字符串实际上有500个字符,因为在我从数据库中提取字符串时进行了某种虚拟化篡改。 - user773737
显示剩余5条评论
2个回答

8
也许这样可以让它跑得更快一些:
https:\/\/[a-zA-Z0-9]+\.cloudfront\.net

通常情况下,你的字符集越独特,正则表达式就会运行得越快。


感谢@sbedulin提供的jsperf链接。


1
那似乎减少了半秒钟左右的时间。也许这只是需要很长时间完成的事情之一,很少能够做些什么吗? - user773737
1
@Houseman 我认为你代码中的其他部分正在占用时间,因为在这种情况下它不应该是正则表达式。 - d0nut
5
@Houseman jsperf 展示了更加严格的正则表达式的速度。http://jsperf.com/cloudfront-regex-replace - sbedulin
[a-zA-Z0-9]替换为[^\n]怎么样?肯定一个检查比可能的三个检查更快。 - Tom Burris
1
@TomBurris 不是的。实际上更慢。就像我说的:越独占,越好。https://jsperf.com/test-of-n-on-cloudfront/1 - d0nut
显示剩余5条评论

6

对于如此简单的替换,正则表达式可能不是最快的搜索和替换方法。例如,如果您使用.indexOf()替换搜索,然后使用.slice()进行替换,可以将其加速12-50倍(取决于浏览器)。

我不确定您想要模拟的确切替换逻辑,但这是一种非正则表达式方法,速度更快:

var pos, str, target = "cloudfront.net/";
var pDistro = "https://newDistro.cloudfront.net/"
for(var i = 0; i < urls.length; i++){
    str = urls[i];
    pos = str.indexOf(target);
    if (pos !== -1) {
        results[i] = pDistro + str.slice(pos + target.length);
    }
}

以下是其他人建议的更智能的正则表达式替换,这里进行了比较。更智能的正则表达式确实有助于正则表达式,但仍然比仅使用 .indexOf().slice() 慢,而在 Firefox 中的差异最为显著:

请参见 jsperf: http://jsperf.com/fast-replacer

enter image description here


这里是与 @iismathwizard 建议的 RegExp 进行比较的内容:http://jsperf.com/cloudfront-regex-replace-vs-splice - sbedulin
@sbedulin - 我已将你的jsperf更新到我代码的最新版本(就像现在我的答案中所示),并为测试URL添加了一个子域,因为这是我们要替换的内容,结果发生了变化:http://jsperf.com/cloudfront-regex-replace-vs-splice/2 - jfriend00
谢谢!在Firefox中,indexOf+splice非常快,其他浏览器则需要考虑一下。 - sbedulin
@sbedulin - 我更新了我的jsperf和答案中的图表,展示了更智能的正则表达式替换。 - jfriend00

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接