我一直对这个问题很好奇。虽然我不是一个狂热的程序员,主要是写一些小的Python脚本和几个分子动力学模拟。那么真正的问题是: switch语句有什么用?为什么不能只使用if-else语句?
谢谢你的回答,如果之前已经有人问过这个问题,请给我提供链接。
编辑
S.Lott指出这可能是重复的问题If/Else vs. Switch。如果您想关闭它,请这样做,我会将其保留以供进一步讨论。
我一直对这个问题很好奇。虽然我不是一个狂热的程序员,主要是写一些小的Python脚本和几个分子动力学模拟。那么真正的问题是: switch语句有什么用?为什么不能只使用if-else语句?
谢谢你的回答,如果之前已经有人问过这个问题,请给我提供链接。
编辑
S.Lott指出这可能是重复的问题If/Else vs. Switch。如果您想关闭它,请这样做,我会将其保留以供进一步讨论。
使用switch语句更容易转换为跳转表,当case标签彼此接近时,这可以使得switch语句比if-else更加高效。其思想是把一堆跳转指令依次放置在内存中,然后将值添加到程序计数器中。这样就用一个加法操作替换了一组比较操作。
以下是一些极其简化的伪汇编示例。首先是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
接下来是 Switch 版本:
// 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可以通过编译器进行优化-您将获得更快的代码。
同时,我发现在处理可枚举类型时更加优雅。
总之,switch语句为您提供了性能+代码优雅 :)
以下是一些有用的链接:
通常来说,我会忽略此类低级别的优化,因为它们通常不太重要,而且可能因编译器而异。
我认为主要的区别在于可读性。if/else非常灵活,但当您看到switch时,您立即知道所有测试都针对相同的表达式。
case 1,2,3: do(this); break;
case 4,5,6: do(that); break;
除了.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语句的方式,让代码流程落入多个case中,这种技巧在IT领域非常有用,而且正如一些人所说,这样做还能提高代码运行速度。然而,最重要的也是最不重要的考虑因素是,使用这种方式让代码更加美观,比if/else语句的可读性更强。 :)
一些编译器可以优化Switch语句,使其更好。在某些语言中使用Switch语句存在陷阱。在Java中,Switch不能处理字符串,在VB2005中,Switch语句无法与单选按钮一起使用。
使用Switch语句可以更快且更易读,而If-Then则更通用且适用于更多场合。
唯一情况下开关可能更快的是当您的case值是常量,而不是动态或其他派生值,并且当case数量显着大于计算哈希到查找表中的时间时。
以Javascript为例,它编译成汇编代码在大多数引擎上执行,包括Chrome的V8引擎,在常见情况下,switch语句的执行速度比if-else语句慢30%-60%:http://jsperf.com/switch-if-else/20