Why the switch statement and not if-else?
我已经想了一段时间了。到目前为止,我还不是一个核心程序员,主要是小型的Python脚本,我已经编写了一些分子动力学模拟。对于真正的问题:switch语句的意义是什么?为什么你不能只用if-else语句?
谢谢你的回答,如果之前有人问过这个问题,请指给我链接。
编辑
S.Lott指出,这可能是if/else与switch问题的重复。如果你想关闭,那么就这样做。我会让它继续讨论。
switch结构更容易转换为跳转(或分支)表。这可以使switch语句比case标签紧密结合时的if-else更有效。其思想是在内存中按顺序放置一组跳转指令,然后将值添加到程序计数器中。这将用添加操作替换一系列比较指令。
下面是一些非常简化的psuedo组装示例。首先,if-else版本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | // 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 |
接下来是交换机版本:
1 2 3 4 5 6 7 8 9 10 11 12 | // 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之外的其他值。然而,这应该说明这个概念。
开关可以通过编译器进行优化-您将获得更快的代码。此外,我发现它在处理可枚举类型时更优雅。
总而言之,switch语句为您提供了性能+代码优雅:)
以下是一些有用的链接:
- C中开关与if/else的速度比较#
- 反馈导向开关语句优化(描述开关语句优化的pdf)
我忽略了通常不重要的这类低级优化,可能不同于编译器。
我认为主要的区别是可读性。if/else非常灵活,但是当您看到一个开关时,您马上就会知道所有的测试都是针对同一个表达式的。
为了便于表达,switch/case语句允许您将多个案例组合在一起,例如:
1 2 | case 1,2,3: do(this); break; case 4,5,6: do(that); break; |
为了提高性能,编译器有时可以将switch语句优化为跳转表。
除了在.NET中提到的代码可读性和优化之外,您还可以打开枚举等功能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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语句)的能力是有用的,正如一些人已经说过的,它也更快。也许最重要也是最不重要的考虑是,它只会使代码比if/else更漂亮。:)
某些编译器可以"更好地"优化开关。在某些语言中使用switch语句存在缺陷。在Java中,交换机不能处理字符串,而在VB2005中,切换语句将无法使用单选按钮。开关可以更快更容易阅读,如果是通用的,将在更多的地方工作。
只有当事例值是常量(而不是动态的或派生的)并且事例数明显大于将哈希计算到查找表中的时间时,时间开关才能更快。
Javascript编译为在大多数引擎(包括Chrome的V8引擎)上执行的程序集,其实例是,在常见情况下,switch语句的执行速度要慢30%-60%:http://jspef.com/switch-if-else/20