Donatas
Donatas

Reputation: 111

Lookup function or for in loop?

Which is better for performance - having a lookup function that finds an object in array with a particular ID or just using for in loop with holes in array?

In my situation I've got players array which is dynamic. Let's say 3 players are connected so my array would look like this:

players = [player1, player2, player3]

It would be easy to keep array key as player ID so I would know that player with ID 2 is 3rd in players array and in order to access him I just need to use: players[2] but as the 2nd player leaves he creates an array hole:

players = [player1,,player3]

And as I understand this hole reduces the performance of using array, since I'm using for-in loop a lot, would it be a better to have an array of player objects and instead of leaving array holes I just splice the hole out? But this way I wouldn't be able to keep array key as player ID so I would have to use ID lookup function. So in the end which one of these 2 choices is better for performance? Or there is even better way to fix this issue?

Thank You!

Upvotes: 2

Views: 676

Answers (3)

maraca
maraca

Reputation: 8743

In my opinion the option mentioned by @Jaromanda X in the comments is the best, because the "hole implementation" will become slower and slower, especially when iterating over the players array, because when you keep adding and removing players the arrow grows and becomes very sparse consisting mainly of holes.

var players = {};
players[p.id] = p; // add player p
delete players[p.id]; // remove player p
// player ids have to be unique and should be strings

Here is why the look up is not such a good idea, first I thought this might be easy, but actually this code fails, because you have to update all indexes after the removed player... so better go with the players object.

// ATTENTION: example of FAILING implementation
var players = [];
var map = {};
// add player p
var idx = players.push(p) - 1;
map[p.id] = idx;
// remove player p
players.splice(map[p.id], 1);
delete map[p.id];

Upvotes: 1

Get Off My Lawn
Get Off My Lawn

Reputation: 36299

You can easily check performance yourself using console.time(str) and console.timeEnd(str). Check it using the following examples:

var array = ['player1', 'player2', 'player3'];

// Test using indexOf
console.time('test1');
var val = array.indexOf('player3');
console.timeEnd('test1');

// Test using a for loop
console.time('test2');
for (var i in array) {
    if (i == 'player3') {
        break;
    }
}
console.timeEnd('test2');

Note how the string in time and timeEnd match.

Upvotes: 0

AlphaG33k
AlphaG33k

Reputation: 1678

Use

var players = {
    abc1: player1,
    abc2: player2, 
    abc3: player3
}

Instead of var players = [player1, player2, player3]

Now you can access it via players.abc1.name = "Nicholas" no lookup function needed. If you are only using the ID's to look up each player in an organized way, I would recommend an even simpler approach:

var players = {
    player1: player1,
    player2: player2,
    player3: player3
}

This way you could access it even easier, like players.player1[madeUpPropName] = someValue;

Also, you should never ever us for-in loop on an Array. Use forEach or a basic for loop. Why is using "for...in" with array iteration a bad idea?

Upvotes: 0

Related Questions