2011-03-14 68 views
114

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

+0

你问的是一个固定的子字符串,还是你需要一个正则表达式(使用'regex'标签有点困惑)? – 2011-03-14 08:27:36

+1

这篇文章将有所帮助.. http://stackoverflow.com/questions/1789945/javascript-string-contains – mtk 2012-10-16 09:30:12

+0

如何将字符串拆分为一个数组周围的空白和数组的交集? http://stackoverflow.com/questions/1885557/simplest-code-for-array-intersection-in-javascript – giorgio79 2016-01-12 09:28:08

回答

233

你有两个possibilites:

  1. Regular expression

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

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

Regular expressions seem to be faster(至少在Chrome 10中)。

Performance test - short haystack
Performance test - long haystack


更新2011:

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

你必须看到和尝试为你的自我。这取决于你的需求。例如,一个不区分大小写使用正则表达式可以更快地搜索。


更新2018:

只是为了救人运行测试本身,这里是最常见的浏览器目前的结果,该百分比表示,在未来最快的结果的性能提升(这之间变化浏览器):

铬:的indexOf(〜98%的速度)<-- wow
火狐:缓存正则表达式(〜18%更快)
IE11:缓存正则表达式(〜10%的速度)
边:的indexOf(〜18更快%)
Safari中:缓存正则表达式(〜0。4%的速度)

注意缓存的RegExp是:var r = new RegExp('simple'); var c = r.test(str);而不是:/simple/.test(str)

+1

只有当文本到搜索的结果在手前已知(即没有存储在变量中)时,这可能会稍微快一点,因为正则表达式是在解析时间内由JavaScript引擎创建的。如果要搜索另一个字符串变量内的变量中包含的字符串,indexOf是最快的,因为您需要创建RegExp对象并处理该字符串以便转义特殊字符等。 – 2011-03-14 08:36:30

+6

+1用于进行实验 – 2011-03-14 09:24:58

+0

您的答案已经解释了一切:)感谢您的回答 – 2012-11-30 11:39:52

17

这是否适合您?

string1.indexOf(string2) >= 0 

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

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

+0

但这与其他方法相比如何?这是最快的,还是只是众多方法之一? – Chii 2011-03-14 08:30:52

+0

这应该是快速的,因为它是由JavaScript本身实现的(即它运行本机代码)。任何其他基于JavaScript代码的方法都会变慢。如果您知道确切的字符串,则正则表达式可能会更快一些(因为JavaScript引擎不必走原型链来查找.indexOf)。 – 2011-03-14 08:35:17

+0

如果您需要不区分大小写的搜索,那么您肯定需要构建RegExp对象并调用'test'。 – 2011-03-14 08:51:41

3

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

1

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

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))); 

祝您有个愉快的一天,先生!

+3

当有'test'时没有理由'匹配'方法...检查出最佳答案。 – Bergi 2013-09-05 16:57:58

7

我发现使用一个简单的for循环,迭代字符串中的所有元素,并使用charAt比较执行速度比indexOfRegex快。代码和证明可在JSPerf

ETA:indexOfcharAt都根据上jsperf.com

+0

奇怪的是,一个手工制作的功能比一个内置的更好,但我想这是因为针头只有一个字符。仍然... – Moss 2014-08-16 20:48:46

+0

在Apple iPad(iOS 7.1.1)上通过Chrome Mobile 36.0.1985.57测试。 IndexOf更快。对不起 – rpax 2014-08-30 18:31:09

+0

@rpax CharAt在所有平台(基于jsperf的历史记录)上的速度仍然明显更快,除了Chrome Mobile,其中IndexOf和CharAt的性能与桌面相比都很差。 – wpg4665 2014-09-01 01:31:59

4

在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所示的结果,似乎他们都表现良好。

+0

我可以在里面使用“正则表达式”,作为包含'参数吗?像:'str.includes(“x | y”)';在同一个调用中搜索文字“x”或“y”。 – Patrick 2016-04-15 02:56:32

+0

@Patrick,根据include文件,你不能在其中使用'regex'。一个解决你的问题,'str.includes(“x”)|| str.includes( 'y')的' – zangw 2016-04-15 03:27:23

相关问题