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?

1

2 Answers 2

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.

6
  • 1
    So instead of a huge switch I would have a huge Dictionary instance definition. What do I gain?
    – Aviv Cohn
    Feb 21, 2015 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, 2015 at 23:50
  • 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, 2015 at 23:58
  • 1
    @greyfade: while that's sometimes helpful, most of the time, YAGNI. Feb 22, 2015 at 0: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) Feb 22, 2015 at 0: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.

Not the answer you're looking for? Browse other questions tagged or ask your own question.