Page 1 of 2 12 LastLast
Results 1 to 10 of 14

Thread: Case (Speed) of

  1. #1
    Legendary Member NecroDOME's Avatar
    Join Date
    Mar 2004
    Location
    The Netherlands, Eindhoven
    Posts
    1,059

    Case (Speed) of

    I was wondering how fast case ... of would be with 255 case entry's... How does the compiler handle this type? how does the CPU handle it?
    NecroSOFT - End of line -

  2. #2
    Co-Founder / PGD Elder WILL's Avatar
    Join Date
    Apr 2003
    Location
    Canada
    Posts
    6,107
    Blog Entries
    25

    Case (Speed) of

    Wow, great question. I might seek this one out myself if none of our FPC friends come to answer it.

    It's likely to come down to how it's compiled into assembly code though. FPC has several optimizations that it uses, but they are not the same as what the dcc32.exe compiler in Delphi would do. So I guess you could say that the answer would be different from compiler to compiler.

    I can't go more in depth than that unfortunately so hopefully someone with experience in either the FreePascal or Delphi compiler can give us some more insight.
    Jason McMillen
    Pascal Game Development
    Co-Founder





  3. #3

    Case (Speed) of

    I'm guessing here, but usually for compilers they have different set of rules for generating code for case-statements.

    Highly spread out values such as this:
    Code:
    case i of
      1 : ... ;
      500 : ... ;
      1000..2000 :... ;
    end;
    would compile to code equivalent to a series of IF-statements:
    Code:
    if i=1 then 
    else if i=500 then
    else if &#40;&#40;i>=1000&#41; and &#40;i<=2000&#41;&#41; then
    So higher case hit values gets executed a bit slower than lower values because the CPU process more branches.

    However a "tight" list of values such as this:
    Code:
    case i of
      0 &#58; 
      1 &#58;
      2 &#58;
      3 &#58; 
      4 &#58;
      etc
    generates a jump into a look-up table (a constant array of addresses) so every value takes the same time to execute.
    ZGameEditor - Develop 64kb games for Windows.
    Thrust for Vectrex - ROM-file and 6809 source code.

  4. #4
    Legendary Member NecroDOME's Avatar
    Join Date
    Mar 2004
    Location
    The Netherlands, Eindhoven
    Posts
    1,059

    Case (Speed) of

    OK thanks, I need the second , case 1: 2: 3: etc of

    (I'm gonna use it for a scripting engine, to execute instructions)
    NecroSOFT - End of line -

  5. #5

    Case (Speed) of

    Quote Originally Posted by NecroDOME
    OK thanks, I need the second , case 1: 2: 3: etc of

    (I'm gonna use it for a scripting engine, to execute instructions)
    You should use a procedure jump table array for this :-)

    [pascal]
    constructor TMyVM.Create;
    begin
    inherited Create;
    OpcodeJumpTab[0]:=Opcode0;
    OpcodeJumpTab[1]:=Opcode1;
    // ...
    end;

    procedure TMyVM.Opcode0;
    begin
    // ...
    end;

    procedure TMyVM.Opcode1;
    begin
    // ...
    end;

    procedure TMyVM.ExecuteOpcode(Opcode:integer);
    begin
    OpcodeJumpTab[Opcode]();
    end;
    [/pascal]

    where OpcodeJumpTab is defined by

    [pascal]
    OpcodeJumpTab:array[0..LastOpcodeIndex] of procedure of object;
    [/pascal]

  6. #6

    Case (Speed) of

    Quote Originally Posted by VilleK
    Highly spread out values such as this:
    Code:
    case i of
      1 &#58; ... ;
      500 &#58; ... ;
      1000..2000 &#58;... ;
    end;
    would compile to code equivalent to a series of IF-statements:
    Code:
    if i=1 then 
    else if i=500 then
    else if &#40;&#40;i>=1000&#41; and &#40;i<=2000&#41;&#41; then
    So higher case hit values gets executed a bit slower than lower values because the CPU process more branches.

    However a "tight" list of values such as this:
    Code:
    case i of
      0 &#58; 
      1 &#58;
      2 &#58;
      3 &#58; 
      4 &#58;
      etc
    generates a jump into a look-up table (a constant array of addresses) so every value takes the same time to execute.
    Actually, the Delphi 7 compiler use look-up tables even for "tight" parts of case list as well as a kind of binary search for optimizing more spreaded values.
    Overall it does a good job I think.

  7. #7
    Legendary Member NecroDOME's Avatar
    Join Date
    Mar 2004
    Location
    The Netherlands, Eindhoven
    Posts
    1,059

    Case (Speed) of

    however when I sort of have my "compiler" working I will make a little speed test...
    NecroSOFT - End of line -

  8. #8

    Case (Speed) of

    Quote Originally Posted by BeRo
    Quote Originally Posted by NecroDOME
    OK thanks, I need the second , case 1: 2: 3: etc of

    (I'm gonna use it for a scripting engine, to execute instructions)
    You should use a procedure jump table array for this :-)

    [pascal]
    constructor TMyVM.Create;
    begin
    inherited Create;
    OpcodeJumpTab[0]:=Opcode0;
    OpcodeJumpTab[1]:=Opcode1;
    // ...
    end;

    procedure TMyVM.Opcode0;
    begin
    // ...
    end;

    procedure TMyVM.Opcode1;
    begin
    // ...
    end;

    procedure TMyVM.ExecuteOpcode(Opcode:integer);
    begin
    OpcodeJumpTab[Opcode]();
    end;
    [/pascal]

    where OpcodeJumpTab is defined by

    [pascal]
    OpcodeJumpTab:array[0..LastOpcodeIndex] of procedure of object;
    [/pascal]
    That is exactly what I did when I was working on a scripting language and it worked great!
    cheers,
    Paul.

  9. #9

    Case (Speed) of

    Actually, in Delphi and C/C++ switch or case statements are compiled down to a pointer list. So instead of if statements the compiler does a test to see if the pointer index is set and valid, if so then it jumps to the handler with a return at the end. If not then it bypasses and goes to the fallout point.

    I don't know if this is how FPC handles it or not, never actually took the time to look at the generated code . But, I would guess that it would be close.

  10. #10

    Case (Speed) of

    FPC has several ways to handle a case statement. It generates exactly the code you want, without asking To go in more details, the exact method depends a bit on the situation, but most of the time you will see FPC generating a decrement list, i.e.:

    dec eax
    jz @case_label_1
    dec eax
    jz @case_label_2
    dec eax
    jz @case_label_3
    dec eax
    jz @case_label_4
    dec eax
    jz @case_label_5
    dec eax
    jz @case_label_6

    This is a quite fast solution. If the amount of case labels gets large, FPC switches to a jump table. There are more algorithms are available, they get used in more specific cases.

Page 1 of 2 12 LastLast

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •