I have a method that frequently calls a long switch statement and then performs a few lines of code. (Any entry in the switch could be called at any time, so it doesn’t make sense to order them by popularity.)
If I were using another language, like Objective-C, I’d create code blocks, assign them to a dictionary, and retrieve them with a key to find and perform the right bit of code very quickly.
What is a similar strategy in XOJO? It seems the closest solution would be to use a Dictionary, but the values would have to be the AddressOf of methods. I’d rather not have a lot of sub-method calls or the overhead of maintaining a lot of method entries. Have I missed an alternate solution? Is there something coming on the XOJO roadmap?
One strategy would be create a class with a “Run” method that raises an event. Create subclasses for each code block and assign instances of the subclass to the Dictionary.
Example:
var block as MyClass = dict.Lookup( "identifier", nil )
if block isa object then
block.Run( myData )
end if
You can reuse instances for different identifiers and have subclasses of subclasses to avoid code replication.
Thank you, that’s one solution I didn’t think of. But perhaps a lot of subclasses would be more “code” to maintain than an equivalent number of methods? Both the subclass and method approach would be generalized for reuse, as you suggest.
It will have dozens of items in the switch, and I need to call it a dozen times, up to 60 times a second. I don’t “like” it because it has a “bad code smell”—it isn’t how I’d implement this pattern elsewhere, and I want to educate myself on what my options are in XOJO.
And to clarify to no one in particular, I’m not saying, “I think my code will be slow [insert misquote related to premature optimization here]” — without performance testing it, I’m saying that I wanted to educate myself to the options available in the XOJO language that would be an alternative to a big switch statement.
I would think a dictionary lookup would be slower than a select case. I am actually kind of interested in test results for that.
If I needed a select statement that frequently and it turned out to be a time consuming pain point, I would look for ways to make code paths prior to that more specific and not need a select/lookup to begin with. We’re both being kind of vague here, so I have nothing concrete for you to work with.
It is a general best practice to avoid Xojo Dictionary whenever possible. Variants are the cause of many headaches. There are use cases for Dictionary, but a function lookup table? I wouldn’t, personally.
The most obvious solutions are:
1.Dictionary of subclasses
2.Dictionary of delegates
3.Dictionary of XojoScripts
Any of these might be tidier but could also result in an over-engineered solution. Sometimes, the simplest solution is the best.
It is also worth noting that using a dictionary / calling out to another method or script would incur an overhead which might be important since you plan to call the code 60 x per second.
Thus in this case it would fetch the data in one shot in array slot 10009.
The above is of course super simplification.
More realistic case is if your key is string then first it calculates Hash code from your string, so you get Integer or big integer of some sort, then you run it through the bucket algorithm which usually is some sort of Modulus like shown above (with added overflow protection though).
Then it gets the data you requested in one shot without having to ever “search for the data” or loop through the content.
How is your switch statement … switched? Is it by string, integer, something else?
I use the Dictionary 'o Delegates approach in my code and it is very efficient. I doubt that it’s any faster than a Switch statement, and for a certain number of Case statements the Switch statement is more legible and maintainable. Once you get over some threshold of Case statements, though, another approach might serve you better.
Each of your bins allows 3 keys only? It would create a lot of collisions needing extra bins to more 3 keys on each collision. That would lead to walks into main bin (bucket) and its extensions (sub buckets).
I don’t need to try, I’m just curious about the algorithm. Because it is usually a partition algorithm using hashed distribution leading to a start point where it could end as O(1) but with time it will cause collisions of different keys ending inside the same partition (that Xojo calls bins) and every new one will be put in a further position needing a extended time to be found. So yes, hashed algorithms used to cause incremental time access when overpopulated leading to collisions.