[fpc-pascal] If vs case or something else?

Sven Barth pascaldragon at googlemail.com
Thu Jul 6 22:23:50 CEST 2017


On 06.07.2017 18:33, James Richters wrote:
> I can use case statement with strings apparently now, but the thing is,  I create this file myself in an earlier stage, so I do not need to create the file with strings at all, I could use some codes and do something like this:

"case of String" is essentially the same as your chain of if-statements,
the compiler doesn't do any real optimization there.

> Const
>    Thing1 = 1
>     Another_Thing = 2
>     Thing3 = 3
> Var
>     Codenum: Word;
> 
> Case Codenum of
>    Thing1: Begin
>             DoSomethng()
>             DoSomethingElse()
>        End;
>     Another_Thing: Begin
> ... etc ...
> 
> 
> I'm guessing that would be faster as I wouldn't have to keep evaluating all the strings for every condition.   As I was searching for the best way to do this, I came across something about making an Array of Procedures, or something to that effect.   Does anyone know how to do that, and are there performance advantages to doing that?  It's going to take a bit of work to straighten all this out so it would be best if I just did it the best way instead of doing it one way then finding out it could have been better another way.   Any other ideas on how to handle this?
> 
> Any advice on this is greatly appreciated

If you aren't fixed on having to work on a string that would definitely
be best as you could then use a enum or something like that and you a
case statement. The compiler will try to pick a suitable implementation
then (jumptable, linear search), depending on the amount of labels.

Alternatively you can indeed use an array of procedures like this:

=== code begin ===

program tprocarray;

procedure Proc1;
begin
  Writeln('Proc1');
end;

procedure Proc2;
begin
  Writeln('Proc2');
end;

const
  Procs: array[0..1] of TProcedure = (
    @Proc1,
    @Proc2
  );

var
  proc: Longint;
begin
  proc := 1;
  Procs[proc]();
end.

=== code end ===

Of course you can also use an enum as the array index:

=== code begin ===

{$scopedenums on} // just for demonstrations

type
  TProcs = (
    One,
    Two
  );

const
  Procs: array[TProcs] of TProcedure = (
    @Proc1,
    @Proc2
  );

var
  proc: TProcs;
begin
  proc := TProcs.Two;
  Procs[proc]();
end.

=== code end ===

The variant with the enum has the advantage that the compiler will
complain about missing elements if you add one to the enum type.

Though in both cases you should ensure that your index is in range.

In case of many branches the variant with the array (any of the two
variants) should be faster than the case one.

Regards,
Sven



More information about the fpc-pascal mailing list