Wednesday, 15 July 2015

Testing JavaScript Switch and Object speeds

I've been sort-of anti switch for a while now, initially in terms of JavaScript after reading about a great alternative which uses an object of functions which meant I could create a variable with all my switch conditions in it and test that rather than falling through a switch control, but more latterly for PHP where a similar approach can be used.

Earlier this week I was casting my eye over someone else's code and I started waxing lyrical about alternatives to switch and re-wrote his code to do implement the alternative. He, quite rightly, asked if it was quicker than using a switch... which left me stumped. You see I'd looked at the elegance of the code rather than its efficiency, a question of style over substance, so last night I thought I'd work up some tests to see if it really was as slow as I feared:

// Recording Object
var times = {
    "switch": "",
    "object": ""
};

// Testing array
var a = ["0", "1", "2", "0", "1", "2", "0", "1", "2", "0", "1", "2", "0", "1", "2"];

// Switch test
var start_switch = new Date().getTime();
var return_switch = "";
for (var b = 0; b < 50000; ++b) {
    for (var x = 0; x < a.length; x++) {
        switch (a[x]) {
            case "2":
                return_switch += "two";
                break;
            case "1":
                return_switch += "one";
                break;
            default:
                return_switch += "zero";
                break;
        }
    }
}
var end_switch = new Date().getTime();
times["switch"] = end_switch - start_switch;

// Object test
var switch_replacement = {
    "1": function () {
        return "one";
    },
    "2": function () {
        return "two";
    }
};
var start_object = new Date().getTime();
var return_object = "";
for (var c = 0; c < 50000; ++c) {
    for (var y = 0; y < a.length; y++) {
        return_object += (switch_replacement[a[y]]) ? switch_replacement[a[y]]() : "zero";
    }
}
var end_object = new Date().getTime();
times.object = end_object - start_object;

// Results
alert(JSON.stringify(times));

Most of the time the object approach takes about a third again longer than the switch, though every-so-often the object is significantly quicker... though I'm at a loss for how to explain that. In terms of breaking the code down though, it is much more readable, so I think that I'll stick with it despite it being slightly slower.