Is there a known limit to the number of CASEs in a DO/CASE construct? I have a simple construct like
DO CASE
CASE symField == #A4HHST
symClass := #HHST
(...)
ENDCASE
where the compiler crashes if I have more than 668 CASE conditions (reproducable). Since this is a strange number I'm not sure about some violated boundaries. Is there a known limit, and is there possibly a better way to deal with the need of processing several thousand of these translations?
DO/CASE limits?
DO/CASE limits?
Hi Stefan,
There is (was) no such known limit, but I just managed to reproduce the problem here, although in my case I needed to use 1500 case conditions!
This is a compiler bug, but of course indeed this is not the most efficient thing to do this. If all your CASE statements are like those in your code snippet, I would use a hastable/dictionary, which would make the code perform extremely fast and make it more readable I think. Something like:
Just make sure that the hashtable is created only once! (hence the STATIC local in my sample).
Another option would be to use SWITCH instead of DO CASE, but I think the hashtable is a more elegant solution.
There is (was) no such known limit, but I just managed to reproduce the problem here, although in my case I needed to use 1500 case conditions!
This is a compiler bug, but of course indeed this is not the most efficient thing to do this. If all your CASE statements are like those in your code snippet, I would use a hastable/dictionary, which would make the code perform extremely fast and make it more readable I think. Something like:
Code: Select all
USING System.Collections.Generic
FUNCTION CreateTable() AS Dictionary<SYMBOL,SYMBOL>
LOCAL oTable AS Dictionary<SYMBOL,SYMBOL>
oTable := Dictionary<SYMBOL,SYMBOL>{1000}
oTable:Add(#A4HHST, #HHST)
oTable:Add(#ANOTHER, #RESULT)
oTable:Add(#FOO, #BAR)
// ....
RETURN oTable
FUNCTION GetClassFromField(symField AS SYMBOL) AS SYMBOL
STATIC LOCAL oTable := CreateTable() AS Dictionary<SYMBOL,SYMBOL>
IF oTable:ContainsKey(symField)
RETURN oTable[symField]
END IF
RETURN null_SYMBOL
FUNCTION Start() AS VOID
LOCAL symField,symClass AS SYMBOL
symField := #A4HHST
symClass := GetClassFromField(symField)
? symClass
symField := #FOO
symClass := GetClassFromField(symField)
? symClass
Another option would be to use SWITCH instead of DO CASE, but I think the hashtable is a more elegant solution.
Chris Pyrgas
XSharp Development Team
chris(at)xsharp.eu
XSharp Development Team
chris(at)xsharp.eu
-
- Posts: 71
- Joined: Thu Jul 15, 2021 10:46 am
- Location: Germany
DO/CASE limits?
Thank you Chris,
the hashtable is a much smarter solution - especially because we're talking of generated code here which leads to several thousand elements. I have several use cases for this
the hashtable is a much smarter solution - especially because we're talking of generated code here which leads to several thousand elements. I have several use cases for this
DO/CASE limits?
You're welcome!
Just for completeness, using a SWITCH instead of a DO CASE, will also generate code that internally uses a hash table, so it will also be very fast. But not so readable/elegant, when you have so many cases.
Just for completeness, using a SWITCH instead of a DO CASE, will also generate code that internally uses a hash table, so it will also be very fast. But not so readable/elegant, when you have so many cases.
Chris Pyrgas
XSharp Development Team
chris(at)xsharp.eu
XSharp Development Team
chris(at)xsharp.eu
DO/CASE limits?
Chris,
And maybe I should fix it by displaying an error message about "bad code quality"?
Robert
Do you convert your test code into a Github issue?Chris post=25416 userid=313 wrote:Hi Stefan,
There is (was) no such known limit, but I just managed to reproduce the problem here, although in my case I needed to use 1500 case conditions!
And maybe I should fix it by displaying an error message about "bad code quality"?
Robert
XSharp Development Team
The Netherlands
robert@xsharp.eu
The Netherlands
robert@xsharp.eu
DO/CASE limits?
Hi guys,
I would also suggest using the TryGetValue method in this particular case to immediately check and get the value if it is in the dictionary:
Best regards,
Leonid
I would also suggest using the TryGetValue method in this particular case to immediately check and get the value if it is in the dictionary:
Code: Select all
IF oTable:TryGetValue(symField, OUT symFoundClass AS SYMBOL)
RETURN symFoundClass
END IF
Leonid
Best regards,
Leonid
Leonid
DO/CASE limits?
Robert, done!
Leonid, good point!
And note to myself, a SWITCH command does not allow a SYMBOL for its expression
.
Leonid, good point!
And note to myself, a SWITCH command does not allow a SYMBOL for its expression
.
Chris Pyrgas
XSharp Development Team
chris(at)xsharp.eu
XSharp Development Team
chris(at)xsharp.eu
-
- Posts: 71
- Joined: Thu Jul 15, 2021 10:46 am
- Location: Germany
DO/CASE limits?
Thanks again to all. I have chosen Leonid's approach.
DO/CASE limits?
Chris,
The compiler will compare hashcodes, so that is relatively fast.
Robert
In that case use Symbol2String() on the symbol and compare with (uppercase) literal strings,.Chris post=25421 userid=313 wrote:Robert, done!
And note to myself, a SWITCH command does not allow a SYMBOL for its expression
.
The compiler will compare hashcodes, so that is relatively fast.
Robert
XSharp Development Team
The Netherlands
robert@xsharp.eu
The Netherlands
robert@xsharp.eu