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
Switch vs do case
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
-
- Posts: 178
- Joined: Sat Dec 05, 2015 10:44 am
- Location: Germany
Switch vs do case
Wolfgang, Armin,
from help:
Changing your code, Wolfgang, to something like
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
from help:
Armin seems to be right. oVariante:Anwendbarkeit is an expression, that will be executed once, ProgSettings.AttributBautiefe looks like a constant to me.switchstmt : (BEGIN|DO)? SWITCH expression eos
(CASE constantexpression eos
statementBlock ) *
(OTHERWISE) eos
statementBlock )?
END SWITCH? garbage? eos
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
Frank
Switch vs do case
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
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
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
-
- Posts: 178
- Joined: Sat Dec 05, 2015 10:44 am
- Location: Germany
Switch vs do case
Hi Wolfgang,
Frank
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.Only Robert or Chris can answer if the use of a (strong typed) property has a performance penalty when compared to a local variable.
Frank
Switch vs do case
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
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
XSharp Development Team
The Netherlands
robert@xsharp.eu
The Netherlands
robert@xsharp.eu
Switch vs do case
Hi Robert,
thank you very much - I will adjust my code.
Wolfgang
thank you very much - I will adjust my code.
Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
Switch vs do case
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
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
-
- Posts: 178
- Joined: Sat Dec 05, 2015 10:44 am
- Location: Germany
Switch vs do case
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
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
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
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
XSharp Development Team
The Netherlands
robert@xsharp.eu
The Netherlands
robert@xsharp.eu