Reputation: 2096
newbie question here: I have a 'switch' containing numerous strings. Is there a speed advantage in splitting it alphabetically, like this?
switch(myString.substring(0,1)){
case "a" : switch(myString){
case "a string beginning with a" : runCode(); break;
case "another string beginning with a" : runCode(); break;
} break;
case "b" : switch(myString){
case "by golly another string" : runCode(); break;
case "blimey - hundreds of strings" : runCode(); break;
//... etc
Or does a scripted language read every line anyway, just to find the closed brackets?
Upvotes: 4
Views: 10837
Reputation: 14708
I guess the correct answer could be empirically measured -- and could vary from one JavaScript Execution Engine to another.
Basically we need to look at what the best case the compilation of the script could be compiled to in terms of pseudo code.
Worst case would be a naive sequential set of string compares -- i.e. it sequentially evaluates each case lable doing a string compare -- With all the speed claims over the past few years, I doubt that any of the major engines would do this, unless the number of case lables are few (say 2 or 3).
For lager number of case label, the best execution speed would be for the engine to first create a hash table of all the case labels (done once when the script loads), and then whent the switch statement is executed, calculate the hash value of the input and lookup a set of possible target values for final string compare.
IF the execution engine does this, than the nesting of the switch statement would actually double the time taken -- and hence slowing the speed of execution.
So generally, for modern javascript engines (those used in browsers), trust the system to do the right thing without making unreadable code -- for old and obscure javascript engines (the ones used server side which are not Node.JS) test out what you do.
Upvotes: 1
Reputation: 37506
Yes and no. You'd see a minimum speed gain, but not worth the code readability lost from this sort of structure. A switch statement is like a giant block of if-else statements. It has to go from one case to another until it finds what it's looking for, just like with the if-elseif-else structure equivalent to it. Thus all you're doing is to helping it skip over a handful of conditions. The nested switch statements, especially the way written here, are less readable for most developers than a straight up if-elseif-else hierarchy.
Upvotes: 6
Reputation: 873
I haven't run benchmarks on the JS versions, but I know in PHP there is a slight disadvantage in using switch vs. if/else but the difference is negligible and in certain conditions you gain in readability/maintainability what you lose in speed (imho).
That said, I don't believe you'd gain anything in speed here unless you're more likely to have a,b,c results than x,y,z results. When evaluating the case statements the parser will evaluate each case until it finds a match and then descend into that code.
So if you have answers that come up more frequently than others and put those to the top it would technically save time in evaluating, but I think the time saved would be negligible. That is, a benchmark loop over it a couple thousand times would probably show microsecond differences. I'm too lazy to actually test that, but that's my best guess on it.
And nest switch statements are generally shunned as they're not very pretty and can be hard to read, which can introduce errors and or frustrated coworkers. :)
Upvotes: 1
Reputation: 154908
I don't think you should mind such optimization. I would say it's better to create an object with the functions to be executed, so that you don't need exessive lookup code, but just something like this:
var obj = {
"aa": runCode,
"ab": something,
"ba": foo,
"bb": bar
};
Then you can execute with only this, instead of switch
es inside switch
es. It will look up the correct function internally, which I really think is faster than doing such things yourself:
obj[myString]();
Upvotes: 5