1

I'm building a data structure for storing tile data from isometric maps. I'm currently using a multidimensional array with 3 axis.

var tile = tilesArray[X][Y][Z];

I'm wondering if it would be faster to use a for loop to find data

tilesArray[i] = tileObject

function getTile(x, y, z) {

    //loop through the tiles till we find the right one
    for (var i = 0; i < tilesArray.length; i += 1) {

        //grab the tile
        var tile = tilesArray[i];

        //check the tile position to see if it is the one requested
        if (tile.position[0] = x && tile.position[1] = y && tile.position[2] = z) {
            return tile;
        }   
    }

    //if the tile is not found and we fall out of the for loop return false
    return false;
}

So to recap

var tile = tilesArray[X][Y][Z];

vs

var tile = getTile(x, y, z);
2
  • 1
    [ jsperf.com ] - but in general, the array access will always be faster here, since there is no function call overhead. Commented Jun 10, 2011 at 10:02
  • benchmark Commented Jun 10, 2011 at 10:09

5 Answers 5

1

If there will be mostly random access and a lot of gaps then you could encapsulate an associative array looking like this

var store = {};

function setTile(x, y, z, tile) {
    k = x*1000000 + y*1000 + z;
    store["K" + k] = tile;
}

function getTile(x, y, z) {
    k = x*1000000 + y*1000 + z;
    return store["K" + k];
}

setTile(1, 7, 5, "1-7-5");
alert (getTile(1,7,5));

It is not as fast as the multidimensional array, but it is definitely faster than iteration and an space saver in comparison to the array.

The example would support indexes up to 999 though

Sign up to request clarification or add additional context in comments.

1 Comment

I think I will use this in another system. I can't use it for the tiles as indexes could end up in the 100k. Its a good idea though.
0

Benchmark

The object is 2/3 times as slow in chrome 12.

The object is 1000 times slower in firefox 4. (Basically arrays are really fast in FF4, about a 1000 times faster then chrome)

Becuase the Object is nice and OO and doesn't involve having a 3 dimensional array with a LOT of gaps I would recommend using it as its just generally a better way to store data.

4 Comments

but would it be a serious problem if I'm accessing the data a lot? I need to be able to do this ~1000 times a second for path finding.
@RobertHurst Depends are the tiles moving around? You could cache or memoize the get function if the position is static.
@RobertHurst if you run the test in FF4 you'll see FF4 is optimised to hell for array access so that completely changes things.
Interesting. I realize Its not an easy question to answer but I appreciate the insight. Thank you.
0

Direct array access is the fastest you can get in most languages I think, especially when compared to a loop + function call. No offense, but this sounds like a bad idea :) Keep it as is.

2 Comments

unfortunatly, Javascript has no real Arrays and it's not as fast as array access in other c-like languages. However, it'll still be faster in this situation.
Yeah I'm not implying it's the fastest way across all languages, but for the use case at hand, and especially the proposed alternative, it sounds much better.
0

It depends on the type of access you will do really. Will it be mostly insertions and then sequential access? Then the linear storage such as linked list with a access function might be better.

Will be mostly individual random access? then array access is definitely fastest.

Comments

0

Array indexing is approx. 3 times faster, using the test below and executed in node.js (Google V8 engine). It indexes the same element. You definitely want to try indexing random elements to get a better feel for how they compare.

var tilesArray = createTileArray();

function createTileArray()
{
    var rank = 1000;
    var start = new Date();

    // Define
    var ar = new Array(3);

    // Create
    for (var i=0; i < 3; i++)
    {
        ar[i] = new Array(rank);

        for (var j=0; j < rank; j++)
        {
            ar[i][j] = new Array(rank);
        }
    }

    // Fill
    for ( var i = 0; i < 3; i++) {
        for ( var j = 0; j < rank; j++) {
            for ( var k = 0; k < rank; k++) {
                ar[i.valueOf()][j.valueOf()][k.valueOf()] = 3;
            }
        }
    }

    var end = new Date();

    console.log("Created array in: " + (end-start) + "ms");

    return ar;
}

function getTile(array, x, y, z) {

    // loop through the tiles till we find the right one
    for (var i = 0; i < array.length; i++) {

        // grab the tile
        var tile = array[i];

        // check the tile position to see if it is the one requested
        if (tile[0] === x && tile[1] === y && tile[2] === z) {
            return tile;
        }   
    }

    // if the tile is not found and we fall out of the for loop return false
    return false;
}

function arrayIndexing(array, loopCount)
{
    var start = new Date();

    for (var i = 0; i < loopCount; i++) {
        var elem = array[1][2][3];
    }

    var end = new Date();
    console.log("Array indexing in: " + (end-start) + "ms");
}

function loopIndexing(array, loopCount)
{
    var start = new Date();

    for (var i = 0; i < loopCount; i++) {
        getTile(array, 1, 2, 3);
    }

    var end = new Date();

    console.log("Loop indexing in: " + (end-start) + "ms");
}

var loopCount = 1000000;

arrayIndexing(tilesArray, loopCount);
loopIndexing(tilesArray, loopCount);

2 Comments

That only really tests Chrome though. Firefox 4 is a 1000 times slower whereas Chrome is 2 times slower.
Thanks for the effort. I appreciate it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.