Order of Enum in Case Statement

A while back my manager asked me if the order of the enums in a Delphi case statement changed performance: i.e. Enums in order being faster then those not.  I was pretty sure it didn’t, but thought it was worth checking out.  Time for a test application and some disassembly . . .

Here are my types and variables, which are the same for both examples.

type
  TMyEnum = (my1, my2, my3, my4);
var
  myEnum: TMyEnum;
  val: Char;

Here are the two examples, side by side, with assembly code to follow.  BTW, compiler optimization was turned on.

Case enum in order Case enum out of order
  myEnum := my1;
  case myEnum of
    my1: val := '1';
    my2: val := '2';
    my3: val := '3';
    my4: val := '4';
  else
    val := '?';
  end;
  myEnum := my1;
  case myEnum of
    my3: val := '3';
    my1: val := '1';
    my4: val := '4';
    my2: val := '2';
  else
    val := '?';
  end;
—– Disassembly —–
case myEnum of case myEnum of
BF9E sub al,$01 C00A sub al,$01
BFA0 jb $bfae C00C jb $c01e
BFA2 jz $bfb2 C00E jz $c026
BFA4 dec al C010 dec al
BFA6 jz $bfb6 C012 jz $c01a
BFA8 dec al C014 dec al
BFAA jz $bfba C016 jz $c022
BFAC jmp $bfbe C018 jmp $c02a
my1: val := ‘1′; my3: val := ‘3′;
BFAE mov bl,$31 C01A mov bl,$33
BFB0 jmp $bfc0 C01C jmp $c02c
my2: val := ‘2′; my1: val := ‘1′;
BFB2 mov bl,$32 C01E mov bl,$31
BFB4 jmp $bfc0 C020 jmp $c02c
my3: val := ‘3′; my4: val := ‘4′;
BFB6 mov bl,$33 C022 mov bl,$34
BFB8 jmp $bfc0 C024 jmp $c02c
my4: val := ‘4′; my2: val := ‘2′;
BFBA mov bl,$34 C026 mov bl,$32
BFBC jmp $bfc0 C028 jmp $c02c
val := ‘?’; val := ‘?’;
BFBE mov bl,$20 C02A mov bl,$20

Same number of lines of assembly code. There may be some internal CPU optimization, but I don’t expect there is any.

Conclusion: Order of the enum in the case statement does not change performance.  Anyone else have any details I missed, or evidence to the contrary?  I guess the next step is to test it in .NET and IL. . . .

Tags: , , , ,

3 Responses to “Order of Enum in Case Statement”

  1. I think the issue is if the order matters with respect to the most probable cases. That is to say if your enum has options a-b-c and 90% of the time it is option a, then you should put the code for option a first.

  2. A while ago I did a similar test and wrote down my results here:

    http://www.delphipraxis.net/topic41187_delphiinternals+compilerverhalten+bei+case+statements.html&highlight=

    You should be able to read German, though ;)

    Regards
    Daniel

  3. Thaddy de Koning says:

    Although the compiler always optimizes a case loop to be in-order,
    Olivier is right: You also need to watch your algoritm.

    That also implies that when you know some code is more likely to occur than other code in the case loop, you need to enforce it by evaluating from a low (the lowest) const value.

    But that assumes the compiler will optimize from low to high, and that may not be the case: the compiler may also optimize high to low….
    Some compilers do…

    All in all, Olivier: it is pretty dangerous to rely on perceived optimizations that you can not be sure about and maybe version dependent.
    In your case: you can better write out your algoritm in such a way that the optimization you want is enforced, i.e. f.e. by evaluating the most commonly encountered code first by means of if/then…/else /case/endcase

Leave a Reply