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

时间:2021-12-22 11:44:48

I've been wondering this for some time now. I'm by far not a hardcore programmer, mainly small Python scripts and I've written a couple molecular dynamics simulations. For the real question: What is the point of the switch statement? Why can't you just use the if-else statement?

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

Thanks for your answer and if this has been asked before please point me to the link.

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

EDIT

S.Lott has pointed out that this may be a duplicate of questions If/Else vs. Switch. If you want to close then do so. I'll leave it open for further discussion.

S.Lott指出,这可能是问题If / Else vs. Switch的重复。如果你想关闭,那么这样做。我将把它留待进一步讨论。

8 个解决方案

#1


A switch construct is more easily translated into a jump (or branch) table. This can make switch statements much more efficient than if-else when the case labels are close together. The idea is to place a bunch of jump instructions sequentially in memory and then add the value to the program counter. This replaces a sequence of comparison instructions with an add operation.

switch结构更容易转换为跳转(或分支)表。当case标签靠近时,这可以使switch语句比if-else更有效。我们的想法是在内存中依次放置一堆跳转指令,然后将值添加到程序计数器中。这将使用添加操作替换一系列比较指令。

Below are some extremely simplified psuedo-assembly examples. First, the if-else version:

下面是一些非常简化的伪装配示例。首先,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

Next is the switch version:

接下来是交换机版本:

    // 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

You can see that the resulting assembly code is much more compact. Note that the value would need to be transformed in some way to handle other values than 1, 2 and 3. However, this should illustrate the concept.

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

#2


Switch can be optimized by compiler - you will get faster code.
Also I find it to be more elegant when dealing with enumerable types.

可以通过编译器优化开关 - 您将获得更快的代码。在处理可枚举类型时,我发现它更优雅。

To sum up switch statement gives you performance + code elegance :)

总结一下switch语句给你的性能+代码优雅:)

Here are some useful links:

以下是一些有用的链接:

#3


For expressiveness, the switch/case statement allows you to group multiple cases together, for example:

为表达性,switch / case语句允许您将多个案例组合在一起,例如:

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

For performance, compilers can sometimes optimize switch statements into jump tables.

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

#4


I'm ignoring this type of low level optimization as usually unimportant, and probably different from compiler to compiler.

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

I'd say the main difference is readability. if/else is very flexible, but when you see a switch you know right away that all of the tests are against the same expression.

我要说的主要区别在于可读性。 if / else非常灵活,但是当你看到一个开关时,你就知道所有的测试都是针对同一个表达式的。

#5


Besides the other mentioned Code readability and optimisation in .NET you also get the ability to switch on enums etc

除了在.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;

}

#6


The ability to fall through several cases (intentionally leaving out the break statement) can be useful, and as a few people have already said it's faster as well. Perhaps the most important and least important consideration though, is that it just makes for prettier code than if/else. :)

能够通过几个案例(故意遗漏休息陈述)是有用的,而且有些人已经说过它也更快。也许最重要也是最不重要的考虑因素是它只是制作比if / else更漂亮的代码。 :)

#7


Switch can be optimized "Better" by some compilers. There are pitfalls with using the switch statement in certain languages. In Java, the switch cannot handle strings and in VB2005 the switch statement will not work with radio buttons.
Switch can be faster and easier to read, If-Then is more generic and will work in more places.

某些编译器可以优化“更好”的开关。在某些语言中使用switch语句存在缺陷。在Java中,交换机无法处理字符串,在VB2005中,switch语句不能用于单选按钮。 Switch可以更快更容易阅读,If-Then更通用,可以在更多地方使用。

#8


The only time switches can be faster are when your case values are constants, not dynamic or otherwise derived, and when the number of cases is significantly larger than the time to calculate a hash into a lookup table.

唯一的时间切换可以更快是当您的案例值是常量,而不是动态或以其他方式派生,并且案例数量明显大于计算哈希到查找表的时间。

Case in point for Javascript, which compiles to assembly for execution on most engines, including Chrome's V8 engine, is that switch statements are 30%-60% slower to execute in the common case: http://jsperf.com/switch-if-else/20

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

#1


A switch construct is more easily translated into a jump (or branch) table. This can make switch statements much more efficient than if-else when the case labels are close together. The idea is to place a bunch of jump instructions sequentially in memory and then add the value to the program counter. This replaces a sequence of comparison instructions with an add operation.

switch结构更容易转换为跳转(或分支)表。当case标签靠近时,这可以使switch语句比if-else更有效。我们的想法是在内存中依次放置一堆跳转指令,然后将值添加到程序计数器中。这将使用添加操作替换一系列比较指令。

Below are some extremely simplified psuedo-assembly examples. First, the if-else version:

下面是一些非常简化的伪装配示例。首先,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

Next is the switch version:

接下来是交换机版本:

    // 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

You can see that the resulting assembly code is much more compact. Note that the value would need to be transformed in some way to handle other values than 1, 2 and 3. However, this should illustrate the concept.

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

#2


Switch can be optimized by compiler - you will get faster code.
Also I find it to be more elegant when dealing with enumerable types.

可以通过编译器优化开关 - 您将获得更快的代码。在处理可枚举类型时,我发现它更优雅。

To sum up switch statement gives you performance + code elegance :)

总结一下switch语句给你的性能+代码优雅:)

Here are some useful links:

以下是一些有用的链接:

#3


For expressiveness, the switch/case statement allows you to group multiple cases together, for example:

为表达性,switch / case语句允许您将多个案例组合在一起,例如:

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

For performance, compilers can sometimes optimize switch statements into jump tables.

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

#4


I'm ignoring this type of low level optimization as usually unimportant, and probably different from compiler to compiler.

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

I'd say the main difference is readability. if/else is very flexible, but when you see a switch you know right away that all of the tests are against the same expression.

我要说的主要区别在于可读性。 if / else非常灵活,但是当你看到一个开关时,你就知道所有的测试都是针对同一个表达式的。

#5


Besides the other mentioned Code readability and optimisation in .NET you also get the ability to switch on enums etc

除了在.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;

}

#6


The ability to fall through several cases (intentionally leaving out the break statement) can be useful, and as a few people have already said it's faster as well. Perhaps the most important and least important consideration though, is that it just makes for prettier code than if/else. :)

能够通过几个案例(故意遗漏休息陈述)是有用的,而且有些人已经说过它也更快。也许最重要也是最不重要的考虑因素是它只是制作比if / else更漂亮的代码。 :)

#7


Switch can be optimized "Better" by some compilers. There are pitfalls with using the switch statement in certain languages. In Java, the switch cannot handle strings and in VB2005 the switch statement will not work with radio buttons.
Switch can be faster and easier to read, If-Then is more generic and will work in more places.

某些编译器可以优化“更好”的开关。在某些语言中使用switch语句存在缺陷。在Java中,交换机无法处理字符串,在VB2005中,switch语句不能用于单选按钮。 Switch可以更快更容易阅读,If-Then更通用,可以在更多地方使用。

#8


The only time switches can be faster are when your case values are constants, not dynamic or otherwise derived, and when the number of cases is significantly larger than the time to calculate a hash into a lookup table.

唯一的时间切换可以更快是当您的案例值是常量,而不是动态或以其他方式派生,并且案例数量明显大于计算哈希到查找表的时间。

Case in point for Javascript, which compiles to assembly for execution on most engines, including Chrome's V8 engine, is that switch statements are 30%-60% slower to execute in the common case: http://jsperf.com/switch-if-else/20

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