Switch to something like “Blocks”?

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?

John

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.

3 Likes

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? :thinking: Both the subclass and method approach would be generalized for reuse, as you suggest.

Is there any particular reason why you don’t like your current method?

An alternative could be to use XojoScript but I imagine it would result in slower execution.

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.

How do you select the “key”? Lots of ifs before the switch?

No, it’s just a big switch statement.

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. :sweat_smile:

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.

1 Like

I just can’t understand what you are writing. The impression is that it could be better done, but I have no idea why you need a label and a codeblock.

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.

2 Likes

A dictionary lookup should be faster if its many items.

Since by definition dictionary lookup speed is O(1) while select case is O(n)

Though there may be constant overhead in the dictionary, making it not give benefits until you have enough elements in the number of cases.

2 Likes

Interesting, I thought the Dictionary lookup would have been hindered by needing to search and the process of hashing the Variant key.

Dictionaries are never “searched”

Its a hash table.

A simplification to explain it would be to do

100009 mod 90000 = 10009

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.

2 Likes

Nope, they are.

Dictionaries put you in a block that possibly contains your key, then from there is starts a search.

Depends on the type of dictionary under the hood.

My dictionaries (in my plugins’) would never search for anything. But it would have sub bucket dictionary.

So if there is serious collision in the hash keys then you might need to do maybe 3 shots. (to dive into the sub buckets)

1 Like

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).

No as i said each of them can have sub dictionary.

You can try them out in the CoreClasses plugin.

Xojo Dictionary performs quite well also though (I dont know what collishion algorithm they use though)

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.

The simplest solution is always the best.

2 Likes