xsharp.eu • Switch vs do case - Page 2
Page 2 of 3

Switch vs do case

Posted: Fri Sep 15, 2017 7:42 am
by wriedmann
Hi Armin,

you can use only constant expressions in switch statements. In my case the compare values are configuration settings.

Wolfgang

Switch vs do case

Posted: Fri Sep 15, 2017 8:27 am
by Frank Maraite
Wolfgang, Armin,

from help:
switchstmt : (BEGIN|DO)? SWITCH expression eos
(CASE constantexpression eos
statementBlock ) *
(OTHERWISE) eos
statementBlock )?
END SWITCH? garbage? eos
Armin seems to be right. oVariante:Anwendbarkeit is an expression, that will be executed once, ProgSettings.AttributBautiefe looks like a constant to me.

Changing your code, Wolfgang, to something like

Code: Select all

local Anwendbarkeit as string // or whatever
Anwendbarkeit := oVariante:Anwendbarkeit
do case
case Anwendbarkeit == ProgSettings.AttributBautiefe
does in important change: it calls oVariante:Anwendbarkeit only once. What if there are sideeffects in this call? What if it causes the execution of thousands of lines of code to evaluate it?

Frank

Switch vs do case

Posted: Fri Sep 15, 2017 8:59 am
by wriedmann
Hi Frank,

the compiler does not consider ProgSettings.AttributBautiefe a constant, and it is not a constant. It could be changed every time (it is a static readonly property that is set at program start).

Yes, I could change my code to not use the property anymore, but use a local variable instead. In my VO code I'm doing this also when the access variables are not strongly typed.

Only Robert or Chris can answer if the use of a (strong typed) property has a performance penalty when compared to a local variable.

Personally I prefer to use the property to have better readable code.

Wolfgang

Switch vs do case

Posted: Fri Sep 15, 2017 9:11 am
by Frank Maraite
Hi Wolfgang,
Only Robert or Chris can answer if the use of a (strong typed) property has a performance penalty when compared to a local variable.
even a strongly typed property can have thousands of lines of code behind. You don't know. And even if you know at the time you write this CASE block, the implementation of the property may change in the future causing all kinds of problems.

Frank

Switch vs do case

Posted: Fri Sep 15, 2017 11:20 am
by robert
Wolfgang,

What Frank said: when compiling the case statement the compiler has no "idea" what code is behind the property. So it will generate a property get call for every expression.
I am sure can imagine a class that counts the # of times a property is read (for example to profile the app). Or a property that returns the time in milliseconds.
If the compiler would automatically "cache" the result of the expression then the result of a do case statement where the property is read more than one time would be quite different from where it is only read one time.

If you as a developer know that it is safe to cache the property, then I would suggest to store it in a local variable.

Robert

Switch vs do case

Posted: Fri Sep 15, 2017 12:13 pm
by wriedmann
Hi Robert,

thank you very much - I will adjust my code.

Wolfgang

Switch vs do case

Posted: Fri Sep 15, 2017 1:43 pm
by Horst
Hi
I was not believing it and was comparing the speed btween do case and switch.

result:
switch 6s
docase 10s
VO2.7 13s

switch
//
// 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
LOCAL nCnt AS INT
LOCAL nFound AS INT
local nZeit as float

nFound := 0
nZeit := Seconds ()
FOR nCnt := 1 UPTO 10000000
FOREACH VAR sDeveloper IN GetDevelopers()
SWITCH sDeveloper:ToUpper()
CASE "FABRICE"
nFound := nFound +1
CASE "CHRIS"
nFound := nFound +1
CASE "NIKOS"
nFound := nFound +1
CASE "ROBERT"
nFound := nFound +1
OTHERWISE
nFound := nFound +1
END SWITCH
NEXT
NEXT

? nFound:ToString()
? ntrim(seconds ()-nZeit)
Console.ReadKey()
RETURN


FUNCTION GetDevelopers AS List<STRING>
VAR aList := List<STRING>{}
aList:Add("Chris")
aList:Add("Fabrice")
aList:Add("Nikos")
aList:Add("Robert")
aList:Add("The Roslyn Developers")
RETURN aList

do case
USING System.Collections.Generic

FUNCTION Start() AS VOID
LOCAL aList := {} AS ARRAY
LOCAL nCnt AS DWORD
LOCAL nCnt2 AS DWORD
LOCAL nArray AS DWORD
LOCAL cString AS STRING
LOCAL nZeit AS FLOAT
LOCAL nFound AS DWORD

local iTicks as int64

aList := GetDevelopers ()
nArray := ALen (aList)

nFound := 0
nZeit := Seconds ()
FOR nCnt2 := 1 UPTO 10000000
FOR nCnt := 1 UPTO nArray
cString := Upper (aList [nCnt])
DO CASE
CASE cString = "FABRICE"
nFound := nFound +1
CASE cString = "CHRIS"
nFound := nFound +1
CASE cString = "NIKOS"
nFound := nFound +1
CASE cString = "ROBERT"
nFound := nFound +1
OTHERWISE
nFound := nFound +1
ENDCASE
NEXT
NEXT

? nFound:ToString()
? NTrim (Seconds()-nZeit)
Console.ReadKey()
RETURN


FUNCTION GetDevelopers () AS array
local aList as array
aList := {}
AAdd (aList, "Chris")
AAdd (aList, "Farbrice")
AAdd (aList, "Nikos")
AAdd (aList, "Chris")
AAdd (aList, "Robert")
AAdd (aList, "The Roslyn Developers")
RETURN aList

Switch vs do case

Posted: Fri Sep 15, 2017 1:53 pm
by Frank Maraite
Hi Horst,

fine but one error. They are the X# developers. Roslyn is made by microsoft.

Please do test the following too

snip
FOR nCnt := 1 UPTO nArray
DO CASE
CASE Upper (aList [nCnt]) = "FABRICE"
nFound := nFound +1
CASE Upper (aList [nCnt]) = "CHRIS"
nFound := nFound +1
snip

Frank

Switch vs do case

Posted: Fri Sep 15, 2017 3:09 pm
by Horst
Hi Frank

26s very bad

Horst

Switch vs do case

Posted: Fri Sep 15, 2017 3:16 pm
by robert
Horst,

So switch is definitely faster
Not much but every millisecond counts.
And, like Frank said, it will warn you if you accidentally include the same value twice.
If you really want a good comparison you should change the DO CASE to use the == operator. The single equals = operator in the VO/Vulcan dialect will match "FABRICE" with "F" too.

Robert