Switch vs do case

This forum is meant for questions and discussions about the X# language and tools
User avatar
Horst
Posts: 337
Joined: Tue Oct 13, 2015 3:27 pm

Switch vs do case

Post by Horst »

Hi

I found this example for X# and was shocked, do my VO always check every CASE ? i was testing it and VO is leaving the DO CASE when one is matching .
so, is there realy a different ?? or do i dont understand this X# example ?

// The SWITCH statement is a replacement for the DO CASE statement
// The biggest difference is that the expression (in this case sDeveloper) is only evaluated once.
// which will have a performance benefit over the DO CASE statement
//
using System.Collections.Generic

Function Start() as void
FOREACH VAR sDeveloper in GetDevelopers()
SWITCH sDeveloper:ToUpper()
CASE "FABRICE"
? sDeveloper, "France"
CASE "CHRIS"
CASE "NIKOS"
? sDeveloper, "Greece"
CASE "ROBERT"
? sDeveloper, "The Netherlands"
OTHERWISE
? sDeveloper, "Earth"
END SWITCH
NEXT
Console.ReadKey()
RETURN
Frank Maraite
Posts: 178
Joined: Sat Dec 05, 2015 10:44 am
Location: Germany

Switch vs do case

Post by Frank Maraite »

Hi Horst,

yes, VO was leaving when a match was found. But if you have a thousend CASE's und the last one matches, it did 999 comparisons/test first. The same with X# of course. In the case of sDeveloper:ToUpper() it will execute this method call 999! times for nothing.

SWITCH does one test and then knows what to do.

But switch does more: it checks at compile time if there are to identical conditions. This is valid code:

DO CASE
CASE var == "a"
DoSomething()
CASE var == "b"
.
.
.
CASE var == "a"
DoAnotherThing()
OTHERWISE
NOP
END CASE

In complex scenarios you might wonder, why DoAnotherThing() never executes.

This is not valid code:

SWITCH var
CASE "a"
DoSomething()
CASE "b"
.
.
.
CASE "a"
DoAnotherThing()
OTHERWISE
NOP
END SWITCH

will generate a compile time error at the last CASE because of identical matches.

Saying that using SWITCH makes your code faster and more error proof.

Frank
User avatar
wriedmann
Posts: 3784
Joined: Mon Nov 02, 2015 5:07 pm
Location: Italy

Switch vs do case

Post by wriedmann »

Hi Horst,

the switch and the do case statement are two completely different beasts.

As Frank wrote, the switch statement is faster and less error prone, but the do case is much, much more flexible.

I can replace only a small fraction of my do case blocks with switch blocks, so both have the right to exist.

The VO help says about the do case:

If this expression evaluates to TRUE, the statements following it up until the next CASE, OTHERWISE, or ENDCASE are executed. Afterwards, control branches to the statement following the next ENDCASE statement

Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
User avatar
Chris
Posts: 4987
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

Switch vs do case

Post by Chris »

Guys,

The way DO CASE is implemented in VO (and x# and vulcan for compatibility), it is just a more fancy alternative to IF..ELSEIF. This code in VO

IF something == 1
...
ELSEIF something == 2
...
ELSEIF something == 3
...
ELSE
...
ENDIF

is identical to

DO CASE
CASE something == 1
..
CASE something == 2
..
CASE something == 3
..
OTHERWISE
...
END CASE

Having said that, I personally prefer the DO CASE syntax, which I think makes the code easier to read so I prefer using it to IF..ELSEIF.

But yes, SWITCH is a very different thing, much more efficient but cannot always be used as a replacement for DO CASE.

Chris
Chris Pyrgas

XSharp Development Team
chris(at)xsharp.eu
FFF
Posts: 1593
Joined: Fri Sep 25, 2015 4:52 pm
Location: Germany

Switch vs do case

Post by FFF »

Frank,
SWITCH does one test and then knows what to do.
Out of curiosity: any idea, how this is realized?

Karl
Regards
Karl
(on Win8.1/64, Xide32 2.20, X#2.20.0.3)
User avatar
robert
Posts: 4567
Joined: Fri Aug 21, 2015 10:57 am
Location: Netherlands

Switch vs do case

Post by robert »

Karl,

This depends on the type of the switch value and the range of values used.
It uses several strategies:
I have seen:
- jumptables based on the values (for example for enums with a small numberof values)
- jumptables based on the hashcode of a string
- sometimes it builds code that looks like a do case / if elseif construct

Robert
XSharp Development Team
The Netherlands
robert@xsharp.eu
User avatar
Chris
Posts: 4987
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

Switch vs do case

Post by Chris »

Hi Karl,

It depends a lot on the data type of the SWITCH statement, the actual values provided by the user and even by the machine where the code is compiled, because some of the implementation is hidden and done directly from the JITter. In general, I am pretty sure the idea is that this code:

SWITCH n
CASE n == 1
// operation1
CASE n == 2
// operation2
CASE n == 3
// operation3
END

gets translated to something like

aLookUpTable := {AddressOf(operation1) , AddressOf(operation2) , AddressOf(operation3)}
JumpToAddress(aLookUpTable[n])

the array is generated only once at compile time (JIT time actually), so every time this code is executed, only one comparison is made and one jump.

But this is a simplified sample and things get much more complicated if the values provided in the CASE statements are not in order (1,3,2 instead of 1,2,3), if there are gaps in between (1,4,6) or the types of the CASE values is not numeric. Still, the compiler tries to be as smart as possible and still generates efficient code, but in many cases additional jumps are required.

So in general yes, SWITCH is faster (and possibly more self-documenting?) than DO CASE, but the speed difference will be hardly noticeable in most cases, so I wouldn't go crazy replacing every single one of my DO CASEs in my existing code to SWITCH, at least not just for the speed benefit. It could make a big difference in tight loops though, where execution speed is critical. Or in places with a very long list of CASE statements, like in the Dispatch() method of the GUI SDK classes for example.

Chris
Chris Pyrgas

XSharp Development Team
chris(at)xsharp.eu
Frank Maraite
Posts: 178
Joined: Sat Dec 05, 2015 10:44 am
Location: Germany

Switch vs do case

Post by Frank Maraite »

Hi Chris,
so I wouldn't go crazy replacing every single one of my DO CASEs in my existing code to SWITCH
after finding my first bug caused by two similar CASE's I replaced all and found a few (one or two) more. It was worth the time.

Frank
User avatar
wriedmann
Posts: 3784
Joined: Mon Nov 02, 2015 5:07 pm
Location: Italy

Switch vs do case

Post by wriedmann »

Hi Frank,

that may be possible for you, but I can replace only very few do case blocks with switch statements.

Please look at this code - do switch will not work:

Code: Select all

do case
case oVariante:Anwendbarkeit == ProgSettings.AttributBautiefe 
    oVariante:Einzelpreis := ....
case oVariante:Anwendbarkeit == ProgSettings.AttributHolzArt
    oVariante:Einzelpreis := ....
case oVariante:Anwendbarkeit == ProgSettings.AttributMaterial
    oVariante:Einzelpreis := ....
otherwise         
    oVariante:Einzelpreis := ....
endcase
or this one:

Code: Select all

do case
case String.IsNullOrEmpty( _oPosition:NumOrd ) .and. ;
        String.IsNullOrEmpty( _oPosition:NumPre )
    lReturn := false
case _oPosition:Angebot .and. String.IsNullOrEmpty( _oPosition:NumPre )
    lReturn := false
case _oPosition:Angebot
    _cDatabaseFile := Path.Combine( ProgSettings.DatabasePath, ;
        "Pre_" + _oPosition:NumPre + ".db" )
case _oPosition:Angebot == false .and. String.IsNullOrEmpty( _oPosition:NumOrd )
    lReturn := false
case _oPosition:Angebot == false
    _cDatabaseFile := Path.Combine( ProgSettings.DatabasePath, ;
        "Ord_" + _oPosition:NumOrd + ".db" )
case ! String.IsNullOrEmpty( _oPosition:NumPre ) .and. ;
        String.IsNullOrEmpty( _oPosition:NumOrd )
    cDatabaseFile := Path.Combine( ProgSettings.DatabasePath, ;
        "Pre_" + _oPosition:NumPre + ".db" )
case ! String.IsNullOrEmpty( _oPosition:NumOrd )
    cDatabaseFile := Path.Combine( ProgSettings.DatabasePath, ;
        "Ord_" + _oPosition:NumOrd + ".db" )
otherwise
    lReturn := false
endcase


Both are examples from my Door Configurator.

Of course you are right, that a switch is better than a do case, but it is not always possible.

Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
ArminBack

Switch vs do case

Post by ArminBack »

Hi Wolfgang,

in generell I agree that not every do case can be replaced by a Switch Statement ...

But why shouldn't your first example be replaced with:

SWITCH oVariante:Anwendbarkeit
CASE ProgSettings.AttributBautiefe
...
CASE ProgSettings.AttributHolzArt
...
CASE ProgSettings.AttributMaterial
...
OTHERWISE
...
END

Just wondering if I'm missing something...

Armin
Post Reply