Forum > General

Did you know this cool if-then-else syntax ?

(1/3) > >>

Basile B.:
This afternoon i was reading some random things on Github
while I suddently found this syntax for writting an if-then-else statement:


--- Code: ---program Project1;
begin
  randomize;
  case random(77) > 44 of
    true: writeln('mlsdfg54f');
    false: case random(43) < 12 of
      true: writeln('54sdfgikeks');
      false: writeln('okiqjksdf5er');
    end;
  end;
  readln;
end.

--- End code ---

 :o , damn how can i never see it before ! (typed my first Pascal SLOC in 2006).
Did you know this syntax ?

By the way, if you want to monitor daily the new Pascal things on GH bookmark this GH search.

User137:
Yes i guess we should all know syntax of case structure. Written with IF isn't any more complicated


--- Code: ---  if random(77) > 44 then writeln('mlsdfg54f')
  else if random(43) < 12 then writeln('54sdfgikeks')
  else writeln('okiqjksdf5er');
--- End code ---

howardpc:
I would be interested to know if this

--- Code: ---case boolVar of
  False: RunFalseRoutine;
  True: RunTrueRoutine;
end;

--- End code ---
is more efficient than

--- Code: ---case boolVar of
  True: RunTrueRoutine;
  False: RunFalseRoutine;
end;

--- End code ---

i. e. does the compiler optimise such constructs however you write them, or can you 'help' the compiler by optimising what might otherwise be a sub-optimal case-variable order, by ordering case variables yourself manually? No doubt inspecting the machine code the compiler produces in the two cases would tell me, only I'm not sufficiently asm-literate to interpret it correctly.

MathMan:

--- Quote from: howardpc on November 28, 2014, 12:09:28 am ---I would be interested to know if this

--- Code: ---case boolVar of
  False: RunFalseRoutine;
  True: RunTrueRoutine;
end;

--- End code ---
is more efficient than

--- Code: ---case boolVar of
  True: RunTrueRoutine;
  False: RunFalseRoutine;
end;

--- End code ---

i. e. does the compiler optimise such constructs however you write them, or can you 'help' the compiler by optimising what might otherwise be a sub-optimal case-variable order, by ordering case variables yourself manually? No doubt inspecting the machine code the compiler produces in the two cases would tell me, only I'm not sufficiently asm-literate to interpret it correctly.

--- End quote ---

Looked it up for you - in essence the answer is yes and no :-)

All the following solely relates to the x86-64 microprocessors. In both cases the compiler seems to generate ("seems to" because it does on my system - FPC 2.6.4 64 bit on Win 7/64 bit)


--- Code: ---longbench.pas:316                         case test of
0000000000444429 807df800                 cmpb   $0x0,-0x8(%rbp)
000000000044442D 7502                     jne    0x444431 <WRAPPERAND+33> // true: statement
000000000044442F eb47                     jmp    0x444478 <WRAPPERAND+104> // false: statement
longbench.pas:318                         true: lAnd( Op2, Size1<<6, Op1, Size1<<6, Op3, Size1<<6 );
0000000000444431 488b05b80f2600           mov    0x260fb8(%rip),%rax        # 0x6a53f0 <U_LONGBENCH_OP3>
... some rubbish deleted
0000000000444476 eb45                     jmp    0x4444bd <WRAPPERAND+173>
longbench.pas:317                         false: lAnd( Op2, Size1<<6, Op1, Size1<<6, Op3, Size1<<6 );
0000000000444478 488b05710f2600           mov    0x260f71(%rip),%rax        # 0x6a53f0 <U_LONGBENCH_OP3>
... some rubbish deleted

--- End code ---

The interesting part are the first three lines of asm. The compiler compares for "false" (the "cmpb   $0x0,-0x8(%rbp)" line) and if the boolean value is not "false" it jumps to the "true" part (the "jne    0x444431 <WRAPPERAND+33>" line). If the value is "false" however the processor skips this instruction and jumps to the "false" part (this is the statement in the third asm line).

To understand what this means in practice we need detour into processor architecture a bit. The x86-64 processors try to optimize process flow via branch prediction. This uses what is called a branch target buffer where conditions of recently taken branches are stored and the processor decides, based on this history, whether a branch will probably been taken or not. A branch misprediction leads to a stall in the pipeline and some serious delay in execution. The whole prediction works pretty damn well for the newer x86-64 processors for code that is repetitively executed (inside a small loop) and does not contain more than a certain number of branches.

What does this mean for you:

 * if you have this kind of branch within a loop and you know which alternative is more likely then put the more likely into the "true" part
 * if you have this kind of branch in a continuous code part that is rarely executed put the less likely into the "true" part

Does that answer your question?

Kind regards,
MathMan

howardpc:

--- Quote from: MathMan on November 28, 2014, 01:45:25 am ---Does that answer your question?

--- End quote ---

Yes, if you are saying that optimisation of case statements is related only to the previous case selection history and the relative likelihoods of any future selections; and that the physical ordering of case variables  in the source (e. g. by ordinal priority) is immaterial.

Navigation

[0] Message Index

[#] Next page

Go to full version