Readability aside, are there any discernable differences (performance perhaps) between using
str.indexOf("src")
and
Your comparison may not be entirely fair. indexOf
is used with plain strings and is therefore very fast; match
takes a regular expression - of course it may be slower in comparison, but if you want to do a regex match, you won't get far with indexOf
. On the other hand, regular expression engines can be optimized, and have been improving in performance in the last years.
In your case, where you're looking for a verbatim string, indexOf
should be sufficient. There is still one application for regexes, though: If you need to match entire words and want to avoid matching substrings, then regular expressions give you "word boundary anchors". For example:
indexOf('bar')
will find bar
three times in bar, fubar, barmy
, whereas
match(/\bbar\b/)
will only match bar
when it is not part of a longer word.
As you can see in the comments, some comparisons have been done that show that a regex may be faster than indexOf
- if it's performance-critical, you may need to profile your code.
Performance wise indexOf
will at the very least be slightly faster than match
. It all comes down to the specific implementation. When deciding which to use ask yourself the following question:
Will an integer index suffice or do I need the functionality of a RegExp match result?
You ask whether str.indexOf('target')
or str.match(/target/)
should be preferred. As other posters have suggested, the use cases and return types of these methods are different. The first asks "where in str
can I first find 'target'
?" The second asks "does str
match the regex and, if so, what are all of the matches for any associated capture groups?"
The issue is that neither one technically is designed to ask the simpler question "does the string contain the substring?" There is something that is explicitly designed to do so:
var doesStringContainTarget = /target/.test(str);
There are several advantages to using regex.test(string)
:
str.match(/target/)
(and rivals str.indexOf('target')
)str
is undefined
or null
, you'll get false
(the desired result) instead of throwing a TypeError
remember Internet Explorer 8 doesnt understand indexOf
.
But if nobody of your users uses ie8 (google analytics would tell you) than omit this answer.
possible solution to fix ie8:
How to fix Array indexOf() in JavaScript for Internet Explorer browsers
Here all possible ways (relatively) to search for string
// 1. includes (introduced in ES6)
var string = "string to search for substring",
substring = "sea";
string.includes(substring);
// 2. string.indexOf
var string = "string to search for substring",
substring = "sea";
string.indexOf(substring) !== -1;
// 3. RegExp: test
var string = "string to search for substring",
expr = /sea/; // no quotes here
expr.test(string);
// 4. string.match
var string = "string to search for substring",
expr = "/sea/";
string.match(expr);
//5. string.search
var string = "string to search for substring",
expr = "/sea/";
string.search(expr);
Here a src: https://koukia.ca/top-6-ways-to-search-for-a-string-in-javascript-and-performance-benchmarks-ce3e9b81ad31
Benchmarks seem to be twisted specially for es6 includes , read the comments.
if you don't need the matches. => Either you need regex and so use test. Otherwise es6 includes or indexOf. Still test vs indexOf are close.
They seem to be the same : https://jsperf.com/array-indexof-vs-includes/4 (if it was different it would be wierd, they mostly perform the same except for the differences that they expose check this)
And for my own benchmark test. here it is http://jsben.ch/fFnA0 You can test it (it's browser dependent) [test multiple time] here how it performed (multiple run indexOf and includes one beat the other, and they are close). So they are the same. [here using the same test platform as the article above].
And here for the a long text version (8 times longer) http://jsben.ch/wSBA2
Tested both chrome and firefox, same thing.
Notice jsben.ch doesn't handle memory overflow (or there limits correctly. It doesn't show any message) so result can get wrong if you add more then 8 text duplication (8 work well). But the conclusion is for very big text all three perform the same way. Otherwise for short indexOf and includes are the same and test a little bit slower. or Can be the same as it seemed in chrome (firefox 60 it is slower).
Notice with jsben.ch: don't freak out if you get inconsistant result. Try different time and see if it's consistent or not. Change browser, sometimes they just run totally wrong. Bug or bad handling of memory. Or something.
ex:
Here too my benchmark on jsperf (better details, and handle graphs for multiple browsers)
(top is chrome)
normal text
https://jsperf.com/indexof-vs-includes-vs-test-2019
resume: includes and indexOf have same perofrmance. test slower.
(seem all three perform the same in chrom)
Long text (12 time longer then normal)
https://jsperf.com/indexof-vs-includes-vs-test-2019-long-text-str/
resume: All the three perform the same. (chrome and firefox)
very short string
https://jsperf.com/indexof-vs-includes-vs-test-2019-too-short-string/
resume: includes and indexOf perform the same and test slower.
Note: about the benchmark above. For the very short string version (jsperf) had an big error for chrome. Seeing by my eyes. around 60 sample was run for both indexOf and includes same way (repeated a lot of time). And test a little bit less and so slower. don't be fooled with the wrong graph. It's clear wrong. Same test work ok for firefox, surely it's a bug.
Here the illustration: (the first image was the test on firefox) waaaa. Suddenly indexOf became superman. But as i said i did the test, and looked at the number of samples it was around 60. Both indexOf and includes and they performed the same. A bug on jspref. Except for this one (maybe because of a memory restriction related problem) all the rest was consistent, it give more details. And you see how many simple happen in real time.
indexOf vs includes => Same performance
test => can be slower for short strings or text. And the same for long texts. And it make sense for the overhead that the regex engine add. In chrome it seemed it doesn't matter at all.
Using indexOf
should, in theory, be faster than a regex when you're just searching for some plain text, but you should do some comparative benchmarks yourself if you're concerned about performance.
If you prefer match
and it's fast enough for your needs then go for it.
For what it's worth, I agree with your colleagues on this: I'd use indexOf
when searching for a plain string, and use match
etc only when I need the extra functionality provided by regular expressions.