Skip to content

What a switch actually compiles to

You've heard that a switch can be faster than an if/else chain, and that it likes dense integer cases starting near zero. Both are true, and the Z80 shows you why in one move: a switch doesn't test your value at all — it uses it as an index to look up where to jump.

The slow way: ask, ask, ask

An if/else chain compares the value against each case in turn. Case 0 is quick; case 9 means nine comparisons and nine branches first. The cost grows with how far down the list you land — linear, and unpredictable:

Z80 · THE IF/ELSE CHAIN
        cp   0
      jp   z, state_idle
      cp   1
      jp   z, state_walk
      cp   2
      jp   z, state_jump    ; ... and on, and on
Every case you don't match is a comparison you still paid for.

The fast way: compute the destination

Instead, lay the destination addresses out in a table. Take the value, double it (each address is two bytes), read the address from the table, and jump straight there. No comparisons — the value is the index:

Z80 · THE JUMP TABLEno compares
        ld   l, a
      ld   h, 0
      add  hl, hl       ; index × 2 (addresses are 2 bytes)
      ld   de, table
      add  hl, de       ; hl -> the slot for this case
      ld   e, (hl)
      inc  hl
      ld   d, (hl)
      ex   de, hl
      jp   (hl)         ; jump to the address we looked up

table:  dw   state_idle, state_walk, state_jump, ...
Case 0 and case 99 cost exactly the same. The work is a multiply-by-two and an indexed read — constant time.

Now the compiler’s habits make sense. It wants dense cases — 0,1,2,3 — because the value is a direct index into the table; gaps mean wasted slots or a fallback. Sparse cases like 1, 1000, 50000 can’t be a clean table, so it quietly falls back to comparisons or a binary search. That’s why “use an enum starting at zero” is real performance advice, not style.

A state machine, a bytecode interpreter’s dispatch loop, a switch over an opcode — all the same trick: don’t ask a long list of questions when the answer can be an address you look up. The Z80 has no switch keyword, so you build the mechanism yourself and see precisely what your compiler has been doing all along.

>Every great programmer started with one instruction.