Reputation: 2128
I was studying big O notation for a technical interview and then I realized that javascript's indexOf
method may have a time complexity of O(N) as it traverses through each element of an array and returns the index where its found.
We also know that a time complexity of O(n^2) (n square) is not a good performance measure for larger data.
So is it a bad idea to use indexOf
inside loops? In javascript, its common to see code where indexOf
method is being used inside loops, may be to measure equality or to prepare some object.
Rather than arrays, should we prefer objects wherever necessary as they provide lookup with constant time performance O(1).
Any suggestions will be appreciated.
Upvotes: 23
Views: 12128
Reputation: 281
based on the browser, the indexOf
has different implementations (using graphs, trees, ...). So, the time complexity for each indexOf
also differs.
Though, what is clear is that implementing indexOf
to have O(n)
would be so naive and I don't think there is a browser to have it implements like a simple loop. Therefore, using indexOf
in a for loop is not the same as using 2 nested for loops.
So, this one:
// could be O(n*m) which m is so small
// could be O(log n)
// or any other O(something) that is for sure smaller than O(n^2)
console.time('1')
firstArray.forEach(item => {
secondArray.indexOf(item)
})
console.time('1')
is different than:
// has O(n^2)
console.time('2')
firstArray.forEach(item => {
secondArray.forEach(secondItem => {
// extra things to do here
})
})
console.time('2')
Upvotes: 1
Reputation: 182
It can be a bad idea to use indexOf
inside loops especially if the dataStructure
you are searching through is quite large.
One work around for this is to have a hash table or dictionary containing the index of every item which you can generate in O(N)
time by looping through the data structure and updating it every time you add to the data structure.
If you push
something on the end of the data structure it will take O(1)
Time to update this table and the worst case scenario is if you push something to the beginning of the data structure it will take O(N)
.
In most scenarios it will be worth it as getting the index will be O(1)
Time.
Upvotes: 9
Reputation: 1390
To be honest, tl;dr. But, I did some speed tests of the various ways of checking for occurrences in a string (if that is your goal for using indexOf. If you are actually trying to get the position of the match, I personally don't know how to help you there). The ways I tested were:
.includes()
.match()
.indexOf()
(There are also the variants such as .search()
, .lastIndexOf()
, etc. Those I have not tested).
Here is the test:
var test = 'test string';
console.time('match');
console.log(test.match(/string/));
console.timeEnd('match');
console.time('includes');
console.log(test.includes('string'));
console.timeEnd('includes');
console.time('indexOf');
console.log(test.indexOf('string') !== 0);
console.timeEnd('indexOf');
I know they are not loops, but show you that all are basically the same speed. And honestly, each do different things, depending on what you need (do you want to search by RegEx? Do you need to be pre ECMAScript 2015 compatible? etc. - I have not even listed all of them) is it really necessary to analyze it this much?
From my tests, sometimes indexOf()
would win, sometimes one of the other ones would win.
Upvotes: 5