2

Often times we see stuff like that in code:

void myFunction(string someValue) {
    if (someValue == "a") {
        // ...
    } else if (someValue == "b") {
       // ...
    } else if (someValue == "c") {
       // ...
    } else {
       // ...
    }
}

This is a basic example of mapping data to actions. Doing this using a big switch or a long series of if else-if is considered a bad practice.

A common approach is to use a Dictionary (or HashMap, etc.) as a replacement. E.g.:

Dictionary<string, Action> _actions = new Dictionary<string, Action>();

// .. fill in the dictionary somewhere

void myFunction(string someValue) {
    _actions[someValue]();
}

Somehow it does feel like a more elegant approach. However I don't see how it is so.


When mapping data to actions, how is a dictionary better than a big/growing switch?

Aviv Cohn
  • 21,190
  • 31
  • 118
  • 178
  • 1
    Also see [Why should a HashMap be used(in functions) to determine which value to return(for a key) when an if else construct can do the job in better time?](http://programmers.stackexchange.com/q/273523/22815) –  Feb 22 '15 at 03:41

2 Answers2

3

What if you have hundreds of values to choose from? How would your switch statement look like? Would it be maintainable? I think not.

What you lose by using a map is very minimal hit in performance because of more misdirection - what you gain is huge, huge boost in maintainability.

As mentioned by greyfade in the comments, you can also change the map during runtime, you are not hardcoding the possible values of the switch statement.

Zavior
  • 1,334
  • 2
  • 11
  • 18
  • 1
    So instead of a huge `switch` I would have a huge `Dictionary` instance definition. What do I gain? – Aviv Cohn Feb 21 '15 at 23:49
  • Why do you have to have huge instance definition? Load the info from a file or some other source? – Zavior Feb 21 '15 at 23:50
  • What if I'm mapping values to actions? My options are either a huge `switch` or a huge `Dictionary` which maps e.g. `string` to `Action`. How is it better? – Aviv Cohn Feb 21 '15 at 23:51
  • 4
    @AvivCohn: It's better in that you can add a given Action associated with a given string *at runtime* instead of statically hard-coding every possible choice. This gives you the option of loading a configuration or dynamically determining the state machine as the program runs. You'd do this, for example, in a game where you want to remap actions to inputs so that the player can change what kind of input layout they want to use. – greyfade Feb 21 '15 at 23:58
  • 1
    @greyfade: while that's sometimes helpful, most of the time, YAGNI. – whatsisname Feb 22 '15 at 00:24
  • 1
    Not a major reason to do this, but using a dictionary prevents mistaken duplicates (I mean something like `if value == a elif value == b` and `elif value == a` *again* whereas one actually meant `c`) – Konrad Morawski Feb 22 '15 at 00:37
2

I terms of readability and maintainability you will be better of with a dictionary if there are anything more than five or six actions.

In terms of performance (depending on language, version, hardware etc. etc.) the trade off is:-

Switch: one comparison per test value plus one branch per action if you assume the values are evenly distributed then you will average 50% of the tests on each pass through the switch. (For C programs with small integer values (like an EVAL) this will be optimized to one branch table look up per pass).

Dictionary: Calculate hash, lookup entry then branch.

So say its 20 instructions to calculate an integer hash, and another 10 to de-reference your branch table then the dictionary starts to outperform the hard coded switch after just 60 test values.

James Anderson
  • 18,049
  • 1
  • 42
  • 72