Recent

Author Topic: Using IF...THEN or CASE?  (Read 878 times)

chuckles1066

  • New Member
  • *
  • Posts: 16
Using IF...THEN or CASE?
« on: November 26, 2020, 04:05:59 pm »
Hi,

Just looking for the most efficient way of doing this.
Code: [Select]
library GenuineDice;
uses MMSystem;
{$mode objfpc}{$H+}

var
  RandomizeAlreadyCalled: Boolean = False;

function Dice: Integer; {$ifdef windows}stdcall{$else}cdecl{$endif};
var
  D1, D2: Integer;
begin
  // call randomize once and never again.
  if not RandomizeAlreadyCalled then begin
    Randomize;
    RandomizeAlreadyCalled := True;
  end;

  D1 := Random(6) + 1;
  D2 := Random(6) + 1;

  Result := D1 * 8 + D2;
// test sound  sndPlaySound('D:\applause2.wav', snd_Async or snd_NoDefault);
end;

exports
  Dice;

begin
end.

So I have thirty-six wav files and I want to play the one that relates to the dice rolls in the above code.  So if D1 = 6 and D2 = 4, I'd play 6-4.wav.

Which way would you suggest is the best way to achieve this, multiple IF....THEN statements or use of a CASE statement?

(I ask because in other languages I've learned (VBA and SQL) CASE statements are sometimes frowned on as being inefficient).

Thank you for reading.


jamie

  • Hero Member
  • *****
  • Posts: 4044
Re: Using IF...THEN or CASE?
« Reply #1 on: November 26, 2020, 04:30:08 pm »

 FileName := IntToStr(D1 * D2)+.'wav';

That will give you 1.wav … 36.wav
The only true wisdom is knowing you know nothing

lucamar

  • Hero Member
  • *****
  • Posts: 3447
Re: Using IF...THEN or CASE?
« Reply #2 on: November 26, 2020, 04:38:46 pm »
If the wave file names corespond to the numbers, as you show, I would simply build the file name from the number returned and forget about if, case, or whatever:

Code: Pascal  [Select][+][-]
  1. { call the libray }
  2. ADice := Dice;
  3. {Then either this: }
  4. D1 = ADice div 8;
  5. D2 := ADice-D1*8;
  6. AFilename := Format('%d-%d.wav', [D1, D2]);
  7. {or simply:
  8. AFilename := Format('%d-%d.wav', [ADice div 8, ADice-D1*8]);
  9. }
  10. {Now do whatever with AFilename}

(I ask because in other languages I've learned (VBA and SQL) CASE statements are sometimes frowned on as being inefficient).

That might be if the language has poor code generation (for whatever reason); in (most compilers of) Pascal, and most other languages I know about, case statements are almost always better optimized than long chains of if...then...else
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.10/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

Warfley

  • Sr. Member
  • ****
  • Posts: 380
Re: Using IF...THEN or CASE?
« Reply #3 on: November 26, 2020, 06:04:52 pm »
I don't know much about the FPC internals, but usually in compiled languages case statements are better for the optimizer because:
1. case statements ignore the order, if statements don't. This means that the compiler can reorder the statements for optimization
2. case statements are simple ordinal matching statements, meaning they can not contain complex logic
3. case statements basically form a jumping table, on consecutive values of a small range, this can therefore be optimized as such

But after all, as you are playing sound files, efficency is none of your concern (the loading and decoding of the file from disk is so much slower than any of your code logic, meaning you probably should go for the solution that gives you the clearest, easiest to read and maintainable code. Usually, if applicable I think these are case statements.

MarkMLl

  • Hero Member
  • *****
  • Posts: 1786
Re: Using IF...THEN or CASE?
« Reply #4 on: November 26, 2020, 06:22:10 pm »
I don't know much about the FPC internals, but usually in compiled languages case statements are better for the optimizer because:

Broadly agreed, but I'd suggest that if you're looking at multiple possibilities which are... not necessarily of equal probability but are of equal rank by some metric, then it's better to write them as a nice evenly-formatted case statement. If you insist on not using a case you could do something like

Code: Pascal  [Select][+][-]
  1. if condition = 0 then
  2.   do_0
  3. else
  4.   if condition = 1 then
  5.     do_1
  6.   else...
  7.  

but it rapidly gets messy. Or you could do

Code: Pascal  [Select][+][-]
  1. if condition = 0 then begin
  2.   do_0;
  3.   exit
  4. end;
  5. if condition = 1 then begin
  6.   do_1;
  7.   exit
  8. end; ...
  9.  

or

Code: Pascal  [Select][+][-]
  1. while true do begin
  2.   if condition = 0 then begin
  3.     do_0;
  4.     break
  5.   end;
  6.   if condition = 1 then begin
  7.     do_1;
  8.     break
  9.   end; ...
  10.  

both of which are frowned upon by purists who insist that  exit  and  break  are merely concealed  goto  statements.

No, if it's a flat list of alternatives like a bulleted list use a case statement, which has the additional advantage that the possibilities are mutually exclusive and you're telling the compiler to enforce that.

MarkMLl
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.

Thaddy

  • Hero Member
  • *****
  • Posts: 10684
Re: Using IF...THEN or CASE?
« Reply #5 on: November 26, 2020, 08:14:45 pm »
(I ask because in other languages I've learned (VBA and SQL) CASE statements are sometimes frowned on as being inefficient).
On the contrary: Case structures in compiled languages like Pascal or C/C++ are highly efficient.
In the case of FreePascal the only exception is with Case for strings which translates to a possibly very long if/then.
I never measured SQL performance for Case, though, and that may also be dependent on the engine you use.
Note that for any language it pays off to put your case loop in natural order because some compilers - not languages - do not optimize this.
« Last Edit: November 26, 2020, 08:25:00 pm by Thaddy »

dseligo

  • New Member
  • *
  • Posts: 37
Re: Using IF...THEN or CASE?
« Reply #6 on: November 26, 2020, 11:40:46 pm »

 FileName := IntToStr(D1 * D2)+.'wav';

That will give you 1.wav … 36.wav

Are you sure?
Maybe:  FileName := IntToStr((D1-1) * 6 + D2)+.'wav';

soerensen3

  • Full Member
  • ***
  • Posts: 213
Re: Using IF...THEN or CASE?
« Reply #7 on: November 26, 2020, 11:45:14 pm »
Though there have been already enough answers to solve your problem I just felt that a lookup table was missing.

You can create a const array as a lookup table and simply use your value as an index.

Code: Pascal  [Select][+][-]
  1. const
  2.   DiceFileNames: array [0..36] of String = ('a.wav', 'b.wav', [...]);
  3.  
  4. var
  5.   FN: String;
  6. begin
  7.   FN:= DiceFileNames[D1 * D2];
  8. end;
  9.  

However I think Jamie's answer in this case is even better but in other cases lookup tables can be a good alternative to case/if statements.
Lazarus 1.9 with FPC 3.0.4
Target: Manjaro Linux 64 Bit (4.9.68-1-MANJARO)

dseligo

  • New Member
  • *
  • Posts: 37
Re: Using IF...THEN or CASE?
« Reply #8 on: November 27, 2020, 01:45:07 am »
Code: Pascal  [Select][+][-]
  1.   FN:= DiceFileNames[D1 * D2];
  2.  

You also got this line wrong.
It should be (if D1 and D2 are in the range from 1 to 6 as they are in the code of original poster):
Code: Pascal  [Select][+][-]
  1.   FN:= DiceFileNames[(D1-1) * 6 + D2 -1];
  2.  

Seenkao

  • Full Member
  • ***
  • Posts: 115
Re: Using IF...THEN or CASE?
« Reply #9 on: November 27, 2020, 03:02:08 am »
So I have thirty-six wav files and I want to play the one that relates to the dice rolls in the above code.  So if D1 = 6 and D2 = 4, I'd play 6-4.wav.
function Dice: Integer;
Если вам надо проиграть файл именно в формате "6-4.waw", то функция в корне не правильная.
Вам не нужно ни каких условий, достаточно вызвать функцию, которая вернёт строку: IntToSrt(D1) + '-' + IntToStr(D2) + '.waw'
И можете воспроизводить данный файл.

Google translate:
If you need to play the file in the "6-4.waw" format, then the function is fundamentally wrong.
You don't need any conditions, just call a function that will return a string: IntToSrt (D1) + '-' + IntToStr (D2) + '.waw'
And you can play this file.

egsuh

  • Hero Member
  • *****
  • Posts: 573
Re: Using IF...THEN or CASE?
« Reply #10 on: November 27, 2020, 09:52:18 am »
Choose whichever is easy for you to understand. Performance difference is really negligible, AFAIK.

 

TinyPortal © 2005-2018