Swift switch statement optimization

When a Swift program is executing a switch statement does it look at each case in turn to see which one to execute? Would it make sense to put the case's more likely to be chosen closer to the top of the statement?

With a switch statement on an enum with a large (over 100) number of cases would it make sense to replace the switch with a dictionary of closures?

Yes, it is evaluated in order.

See proof here: https://stackoverflow.com/questions/25006955/does-the-order-of-the-cases-in-a-switch-statement-have-an-impact-on-speed-of-exe

But IMHO you are looking for optimisations that don't have much impact. Why do you bother ?

In addition, compiler optimises such dispatch of cases:

https://stackoverflow.com/questions/47089878/does-the-order-of-cases-in-a-switch-statement-affect-performance/47090061

Al already noted, semantically switch-cases are evaluated from top to bottom.

With a switch statement on an enum with a large (over 100) number of cases would it make sense to replace the switch with a dictionary of closures?

That depends on your enum. As far as I checked switch on simple enum cases like:

        switch value {
        case .case001:
            break
        case .case002:
            break
        case .case003:
            break
        ...
        case .case100:
            break
        }

It is optimized into a simple multiway branching as found in C-switch statement, even in optimization level -Onone.

SwitchCaseOptimization`MyClass.switchMethod(_:):
    0x100006750 <+0>:   pushq  %rbp
    0x100006751 <+1>:   movq   %rsp, %rbp
    0x100006754 <+4>:   movb   %dil, %al
    0x100006757 <+7>:   movb   $0x0, -0x8(%rbp)
    0x10000675b <+11>:  movq   $0x0, -0x10(%rbp)
    0x100006763 <+19>:  movb   %al, -0x8(%rbp)
    0x100006766 <+22>:  movq   %r13, -0x10(%rbp)
->  0x10000676a <+26>:  movzbl %al, %eax
    0x10000676d <+29>:  movq   %rax, -0x18(%rbp)
    0x100006771 <+33>:  movq   -0x18(%rbp), %rax
    0x100006775 <+37>:  leaq   0x144(%rip), %rcx         ; SwitchCaseOptimization.MyClass.switchMethod(SwitchCaseOptimization.MyCases) -> () + 368
    0x10000677c <+44>:  movslq (%rcx,%rax,4), %rax
    0x100006780 <+48>:  addq   %rcx, %rax
    0x100006783 <+51>:  jmpq   *%rax

(Please be careful, too strong optimization like -O would make whole switch statement into nop, in a simplified all break example as shown above.)

I do expect this optimization would occur in

  • Simple enum cases, no rawValue
  • Enum cases with Int as rawValue, the value range is not huge

I have not tried with enums with some cases having associated values or enum cases with String as rawValue. (Seems internal case representation is a small int even when its rawValues are String.)

So, can you show the definition of your enum?

Swift switch statement optimization
 
 
Q