检查字符串的最快方法是在JavaScript中包含另一个子字符串?


162

我正在处理JavaScript的性能问题。所以我只想问:检查一个字符串是否包含另一个子字符串的最快方法是什么(我只需要布尔值)?您能否提出您的想法和示例代码片段?


您是在问一个固定的子字符串,还是需要一个正则表达式(使用regex标记让我有些困惑)?
蒂姆·皮茨克


如何将字符串拆分为空白周围的数组,并进行数组交集?stackoverflow.com/questions/1885557/...
giorgio79

Answers:


314

您有两个可能性:

  1. 正则表达式

    (new RegExp('word')).test(str)
    // or
    /word/.test(str)
  2. indexOf

    str.indexOf('word') !== -1

正则表达式似乎更快(至少在Chrome 10中如此)。

性能测试-干草堆短
性能测试-干草堆长


2011年更新:

不能肯定地说哪种方法更快。浏览器之间的差异是巨大的。虽然在Chrome 10中indexOf似乎更快,但在Safari 5 indexOf中显然比任何其他方法都慢。

您必须看到并尝试自我。这取决于您的需求。例如,不区分大小写的搜索使用正则表达式会更快。


更新2018:

为了使人们免于自己运行测试,以下是大多数常见浏览器的当前结果,这些百分比表示性能比第二快的结果有所提高(在不同的浏览器中有所不同):

Chrome: indexOf(〜98%快)<-- wow
Firefox:缓存RegExp(
〜18%快) IE11:缓存RegExp(〜10%快)
Edge: indexOf(〜18%快)
Safari:缓存RegExp(〜0.4%快)

请注意,缓存的RegExp是:var r = new RegExp('simple'); var c = r.test(str);相对于:/simple/.test(str)


3
仅在事先知道要搜索的文本(即未存储在变量中)的情况下,这才稍快一些,因为正则表达式是由JavaScript引擎在解析期间创建的。如果你想搜索包含在另一个字符串变量内部变量的字符串的indexOf是最快的,因为你需要创建一个RegExp对象和处理字符串特殊字符转义等
斯蒂芬涌

从经验的indexOf可以是区分大小写的搜索更快,如果你在任何你正在寻找第一次使用.toLowerCase
Hayk酒店Saakian

我正在使用Microsoft的Office Javascript API编写Office 2013应用程序,indexOf但无法使用。我不知道为什么。虽然使用Regex。这是一个极端的情况,但是其他人可能会遇到相同的问题。
Andy Mercer

任何原因substr()都不是可能的解决方案之一?我猜它在许多情况下比RegEx解决方案要快得多。我不知道它与indexOf()的比较如何(因此(如果您将其遗漏了,因为它总是比indexOf()差),那就很好了,也许可以给它添加一个注释。)编辑: 这个JSperf链接显示了一些有趣的东西结果。简短版本:indexOf()是所有方法中最快的方法,但这可能会根据字符串长度和任何重复模式而有所不同。
百程

1
@Bison:如果您已经知道要查找的位置,则只能使用substr。我只关注通用解决方案。
Felix Kling 2014年

17

这对您有用吗?

string1.indexOf(string2) >= 0

编辑:如果string2包含重复的模式,这可能不会比RegExp快。在某些浏览器上,indexOf可能比RegExp慢得多。看评论。

编辑2:当字符串很长和/或包含重复模式时,RegExp可能比indexOf快。查看评论和@Felix的答案。


但这与其他方法相比如何?这是最快的方法,还是仅仅是许多方法之一?
CHII

这应该很快,因为它是由JavaScript本身实现的(即,它运行本机代码)。任何其他基于JavaScript代码的方法都将较慢。如果您知道确切的字符串,则正则表达式可能会快一些(因为JavaScript引擎不必遍历原型链来查找.indexOf)。
Stephen Chung

如果您需要不区分大小写的搜索,则绝对需要构建RegExp对象并调用test
Stephen Chung

3
只需在Safari中运行测试即可。indexOf比其他方法慢一个数量级。因此,实际上不能说哪种方法更快。随浏览器的不同而不同。
菲利克斯·克林

@Felix,这是一个很好的观察(在您亲自尝试之前,请不要信任任何东西)!我模糊地记得在字符串中有很多重复模式的内容,正则表达式的执行速度要比简单的循环比较实现的速度快,因为正则表达式已编译到状态机中,并且比简单的循环回溯速度要快得多,后者必须始终回退-跟踪到下一个字符。+1做实验并将其展示出来!
Stephen Chung

17

最快的

  1. (ES6)包括
    var string =“ hello”,
    substring =“ lo”;
    string.includes(substring);
  1. ES5和较旧的indexOf
    var string =“ hello”,
    substring =“ lo”;
    string.indexOf(substring)!== -1;

http://jsben.ch/9cwLJ

在此处输入图片说明


8

在ES6中,该includes()方法用于确定是否可以在返回truefalse适当时在另一个字符串中找到一个字符串。

var str = 'To be, or not to be, that is the question.';

console.log(str.includes('To be'));       // true
console.log(str.includes('question'));    // true
console.log(str.includes('nonexistent')); // false

这是jsperf之间

var ret = str.includes('one');

var ret = (str.indexOf('one') !== -1);

结果显示在jsperf中,它们似乎都表现良好。


我可以在“ includes”参数中使用“ regex”吗?像:str.includes("x|y"); 在同一调用中搜索文字“ x”或“ y”。
ptkato

@Patrick,根据包含文档,您不能regex在其中使用。一种解决您的问题的方法,str.includes("x") || str.includes('y')
zangw

由于Chrome 59 JavaScript进行了改进,indexOf因此速度大大快于includes(提高了1600%)。目前尚不清楚4400万次迭代/秒和777+百万个 i /秒之间的差异如何影响现实世界的性能,但是移动设备可能会受益匪浅,这indexOf应该是理想的选择。
乍得利维

7

我发现使用简单的for循环,遍历字符串中的所有元素并使用charAt进行比较的效果比indexOf或快Regex。该代码和证明可从JSPerf获得

ETA:根据jsperf.com上列出的Browser Scope数据indexOfcharAt两者在Chrome Mobile上的执行效果都类似


奇怪的是,手动功能要优于内置功能,但是我想这是因为针只是一个字符。仍然...
莫斯

已在Apple iPad(iOS 7.1.1)的Chrome Mobile 36.0.1985.57中进行测试。IndexOf更快。抱歉
rpax 2014年

@rpax CharAt在所有平台上(基于jsperf的历史记录)在Chrome Mobile 之外的运行速度仍然显着提高, Chrome Mobile的IndexOf和CharAt的性能与台式机相比均非常差。
wpg4665

1
我想看看它在NodeJS中的表现如何,这也不是一个很好的例子,因为您只在寻找一个字符而不是一个子字符串。
qodeninja 2014年

这根本不是一个有效的答案。您不是在寻找子字符串,而只是寻找一个字符
Henrik Myntti

3

为了找到一个简单的字符串,使用indexOf()方法和使用正则表达式几乎是相同的:http : //jsperf.com/substring-因此,请选择哪一个看起来更容易编写。



1

这是使用.match()method进行字符串转换的简单方法。

var re = /(AND|OR|MAYBE)/;
var str = "IT'S MAYBE BETTER WAY TO USE .MATCH() METHOD TO STRING";
console.log('Do we found something?', Boolean(str.match(re)));

先生,祝您有个美好的一天!


4
没有理由match什么时候有test方法...请查看最佳答案。
Bergi 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.