Advantage of switch over if-else statement

2018-12-31 13:14发布

What's the best practice for using a switch statement vs using an if statement for 30 unsigned enumerations where about 10 have an expected action (that presently is the same action). Performance and space need to be considered but are not critical. I've abstracted the snippet so don't hate me for the naming conventions.

switch statement:

// numError is an error enumeration type, with 0 being the non-error case
// fire_special_event() is a stub method for the shared processing

switch (numError)
{  
  case ERROR_01 :  // intentional fall-through
  case ERROR_07 :  // intentional fall-through
  case ERROR_0A :  // intentional fall-through
  case ERROR_10 :  // intentional fall-through
  case ERROR_15 :  // intentional fall-through
  case ERROR_16 :  // intentional fall-through
  case ERROR_20 :
  {
     fire_special_event();
  }
  break;

  default:
  {
    // error codes that require no additional action
  }
  break;       
}

if statement:

if ((ERROR_01 == numError)  ||
    (ERROR_07 == numError)  ||
    (ERROR_0A == numError)  || 
    (ERROR_10 == numError)  ||
    (ERROR_15 == numError)  ||
    (ERROR_16 == numError)  ||
    (ERROR_20 == numError))
{
  fire_special_event();
}

23条回答
大哥的爱人
2楼-- · 2018-12-31 13:42

I'm not sure about best-practise, but I'd use switch - and then trap intentional fall-through via 'default'

查看更多
孤独总比滥情好
3楼-- · 2018-12-31 13:44

I would pick the if statement for the sake of clarity and convention, although I'm sure that some would disagree. After all, you are wanting to do something if some condition is true! Having a switch with one action seems a little... unneccesary.

查看更多
忆尘夕之涩
4楼-- · 2018-12-31 13:45

switch is definitely preferred. It's easier to look at a switch's list of cases & know for sure what it is doing than to read the long if condition.

The duplication in the if condition is hard on the eyes. Suppose one of the == was written !=; would you notice? Or if one instance of 'numError' was written 'nmuError', which just happened to compile?

I'd generally prefer to use polymorphism instead of the switch, but without more details of the context, it's hard to say.

As for performance, your best bet is to use a profiler to measure the performance of your application in conditions that are similar to what you expect in the wild. Otherwise, you're probably optimizing in the wrong place and in the wrong way.

查看更多
伤终究还是伤i
5楼-- · 2018-12-31 13:45
while (true) != while (loop)

Probably the first one is optimised by the compiler, that would explain why the second loop is slower when increasing loop count.

查看更多
裙下三千臣
6楼-- · 2018-12-31 13:46

For the special case that you've provided in your example, the clearest code is probably:

if (RequiresSpecialEvent(numError))
    fire_special_event();

Obviously this just moves the problem to a different area of the code, but now you have the opportunity to reuse this test. You also have more options for how to solve it. You could use std::set, for example:

bool RequiresSpecialEvent(int numError)
{
    return specialSet.find(numError) != specialSet.end();
}

I'm not suggesting that this is the best implementation of RequiresSpecialEvent, just that it's an option. You can still use a switch or if-else chain, or a lookup table, or some bit-manipulation on the value, whatever. The more obscure your decision process becomes, the more value you'll derive from having it in an isolated function.

查看更多
看风景的人
7楼-- · 2018-12-31 13:48

Compiler will optimise it anyway - go for the switch as it's the most readable.

查看更多
登录 后发表回答