为什么switch语句而不是if-else?

我一直在想这个一段时间了。 我到目前为止不是一个硬核程序员,主要是小型Python脚本,我写了一些分子动力学模拟。 对于真正的问题: switch语句有什么意义? 为什么你不能使用if-else语句

感谢您的回答,如果之前已经询问,请将我指向链接。

编辑

S.Lott指出,这可能是If / Else vs. Switch问题的重复。 如果你想closures然后这样做。 我会留下来进一步讨论。

开关结构更容易翻译成跳转(或分支)表 。 当case标签靠得很近的时候,这可以使switch语句比if语句更有效率。 这个想法是在内存中依次放置一堆跳转指令,然后将值加到程序计数器。 这用replace操作replace了一系列的比较指令。

下面是一些极其简化的伪装示例。 首先,if-else版本:

// C version if (1 == value) function1(); else if (2 == value) function2(); else if (3 == value) function3(); // assembly version compare value, 1 jump if zero label1 compare value, 2 jump if zero label2 compare value, 3 jump if zero label3 label1: call function1 label2: call function2 label3: call function3 

接下来是交换机版本:

  // C version switch (value) { case 1: function1(); break; case 2: function2(); break; case 3: function3(); break; } // assembly version add program_counter, value call function1 call function2 call function3 

您可以看到生成的汇编代码更加紧凑。 请注意,该值需要以某种方式转换,以处理除1,2和3之外的其他值。但是,这应该说明这个概念。

开关可以通过编译优化 – 你会得到更快的代码。
另外我发现在处理枚举types时它更优雅。

总结switch语句给你的性能 + 代码优雅 🙂

这里有一些有用的链接:

  • 开关与if / else在C#中的速度比较
  • 反馈引导开关语句优化 (pdf描述开关语句优化)

为了expression,switch / case语句允许将多个案例组合在一起,例如:

 case 1,2,3: do(this); break; case 4,5,6: do(that); break; 

为了提高性能,编译器有时可以将switch语句优化为跳转表。

我忽略了这种通常不重要的低级别优化,可能与编译器和编译器不同。

我想说的主要区别是可读性。 如果/ else是非常灵活的,但是当你看到一个开关时,你马上知道所有的testing都是相同的expression式。

除了在.NET中提到的其他代码可读性和优化之外,您还可以打开枚举等

 enum Color { Red, Green, Blue }; Color c = Color.Red; switch (c) // Switch on the enum { // no casting and no need to understand what int value it is case Color.Red: break; case Color.Green: break; case Color.Blue: break; } 

通过几个案例(故意忽略break语句)的能力可能是有用的,正如less数人已经说过的那样,速度也是如此。 也许最重要也是最不重要的考虑因素是它只是比if / else更漂亮。 🙂

开关可以被一些编译器优化为“更好”。 在某些语言中使用switch语句有一些缺陷。 在Java中,交换机无法处理string,在VB2005中,switch语句不能用单选button工作。
开关可以更快,更容易阅读,如果 – 然后是更通用的,将在更多的地方工作。

唯一的时间开关可以更快是当你的案例值是常量,而不是dynamic或其他派生,并且案件的数量显着大于计算散列到查找表中的时间。

对于编译为在大多数引擎(包括Chrome的V8引擎)上执行的程序集,Javascript的例子是,switch语句在常见情况下执行速度要慢30%-60%: http : //jsperf.com/switch-if -else / 20