为什么String.replace()的lambda慢于while循环重复调用RegExp.exec()? [英] Why is String.replace() with lambda slower than a while-loop repeatedly calling RegExp.exec()?

查看:103
本文介绍了为什么String.replace()的lambda慢于while循环重复调用RegExp.exec()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一个问题:

我想处理一个字符串( str )这样任何带括号的数字(由 rgx 匹配)都会被从数组中相应位置取得的值替换( sub ):

I want to process a string (str) so that any parenthesised digits (matched by rgx) are replaced by values taken from the appropriate place in an array (sub):

var rgx = /\((\d+)\)/,
    str = "this (0) a (1) sentence",
    sub = [
            "is",
            "test"
        ],
    result;

结果,给定上面声明的变量,应该是'这是一个测试句'。

The result, given the variables declared above, should be 'this is a test sentence'.

两个解决方案:

这有效

var mch,
    parsed = '',
    remainder = str;
while (mch = rgx.exec(remainder)) { // Not JSLint approved.
    parsed += remainder.substring(0, mch.index) + sub[mch[1]];
    remainder = remainder.substring(mch.index + mch[0].length);
}
result = (parsed) ? parsed + remainder : str;

但我认为以下代码会更快。它具有更少的变量,更简洁,并使用匿名函数表达式(或 lambda ):

But I thought the following code would be faster. It has fewer variables, is much more concise, and uses an anonymous function expression (or lambda):

result = str.replace(rgx, function() {
    return sub[arguments[1]];
});

这也有效,但我的速度错了; 在Chrome中令人惊讶的是(上次我检查时约为50%)变慢了

This works too, but I was wrong about the speed; in Chrome it's surprisingly (~50%, last time I checked) slower!

...

三个问题:


  1. 为什么这个过程在Chrome中显得较慢,而且(例如)在Firefox中更快?

  2. 是否有可能 replace()方法与 while()循环相比,给定更大的字符串或数组会更快?如果没有,除 Code Golf 之外有什么好处?

  3. 有一种方法可以优化这个过程,使其更有效率,并且与功能性的第二种方法一样无忧无虑吗?

  1. Why does this process appear to be slower in Chrome and (for example) faster in Firefox?
  2. Is there a chance that the replace() method will be faster compared to the while() loop given a bigger string or array? If not, what are its benefits outside Code Golf?
  3. Is there a way optimise this process, making it both more efficient and as fuss-free as the functional second approach?

我欢迎任何有关这些流程背后发生的事情的见解。

I'd welcome any insights into what's going on behind these processes.

...

[ Fo(u)r记录:我很高兴在使用'lambda'和/或'functional'这个词时被叫出来。我还在学习这些概念,所以不要以为我确切地知道我在说什么,如果我在这里误用这些条款,请随时纠正我。]

[Fo(u)r the record: I'm happy to be called out on my uses of the words 'lambda' and/or 'functional'. I'm still learning about the concepts, so don't assume I know exactly what I'm talking about and feel free to correct me if I'm misapplying the terms here.]

推荐答案


为什么这个过程在Chrome中显得更慢,(例如)在Firefox中更快?

Why does this process appear to be slower in Chrome and (for example) faster in Firefox?

因为它必须调用(非本机)函数,这是昂贵的。 Firefox的引擎可能能够通过识别和内联查找来优化它。

Because it has to call a (non-native) function, which is costly. Firefox's engine might be able to optimize that away by recognizing and inlining the lookup.


与给定较大字符串或数组的while()循环相比,replace()方法是否有可能更快?

Is there a chance that the replace() method will be faster compared to the while() loop given a bigger string or array?

是的,它必须做更少的字符串连接和分配,并且 - 如你所说 - 初始化的变量更少。然而,你只能测试它来证明我的假设(并且还要看看 http:// jsperf。 com / match-and-substitute / 4 用于其他片段 - 例如,您可以看到Opera优化lambda-replace2,它不使用参数)。

Yes, it has to do less string concatenation and assignments, and - as you said - less variables to initialize. Yet you can only test it to prove my assumptions (and also have a look at http://jsperf.com/match-and-substitute/4 for other snippets - you for example can see Opera optimizing the lambda-replace2 which does not use arguments).


如果没有,Code Golf以外的优势是什么?

If not, what are its benefits outside Code Golf?

我不认为代码高尔夫是正确的术语。软件质量是关于可读性和可理解性的,在其术语中,功能代码的简洁优雅(这是主观的)是使用这种方法的原因(实际上我是'我从未见过替换 exec substring 并重新连接)。

I don't think code golf is the right term. Software quality is about readabilty and comprehensibility, in whose terms the conciseness and elegance (which is subjective though) of the functional code are the reasons to use this approach (actually I've never seen a replace with exec, substring and re-concatenation).


有没有一种方法可以优化这个过程,使其更有效率,并且与功能性第二种方法一样无忧无虑?

Is there a way optimise this process, making it both more efficient and as fuss-free as the functional second approach?

您不需要余数变量。 rgx lastIndex 属性,它将通过 str 自动推进比赛。

You don't need that remainder variable. The rgx has a lastIndex property which will automatically advance the match through str.

这篇关于为什么String.replace()的lambda慢于while循环重复调用RegExp.exec()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆