Is there a more effective (ie. FASTER) was to select from a large list?

I have a custom graphics class (think canvas)… This has one major task and that is to display an image on the screen. This class has a key property with (currently 57 values).
So based on the value of that key, the canvas will be one of 57 images.

Right now the code looks like this (and it does “work”)

private func drawIMAGE(imgKey:Int) {
   switch imgKey {
    case 1 : draw_image_1
    case 2 : draw_image_2
    case 57 : draw_image_57

followed by

private func draw_image_1() { ... drawing code }
private func draw_image_2() { ... drawing code }
private func draw_image_57() { ... drawing code }

So I have a switch (SELECT CASE) statement with 57 conditions, and 57 functions to draw each of the possible images

Why wouldn’t you have a property holding the image to draw and a generalized function that draws that image? Are the functions that draw significantly different?

yes the functions are all quite differnet… and a given image might change (become wider, taller, change colors etc)… but it caches the image … so it only recreates it if it changes

each image is somewhat dynamic, think Xojo IDE controls in the designer

Gotcha, I was thinking more along the lines of your card game.

No worries… the card game is an indexed array… with static images… different situation :slight_smile:

The only way I can think of to make this less gnarly and more easily maintained, at some performance expense, would be using reflection (.NET) or introspection (Xojo, Swift). Then you would make the function call after determining the function name from the imgKey (or call a DrawImage() method in a static class whose name is thusly determined, etc).

Really depends on how this all works.

For instance instead of storing an imageKey with an object, you can store a NSSelector, then use the sendmessage API to execute that function. I’ve used this technique in several places, but not with this many methods.

in Xojo style code

delayed no_arg_delegate

dim funcs() as no_arg_delegate

… now load address of each function into the array ONCE

Sub loadJumpTable()
    // skip position 0
    funcs.append addressof do_nothing
    funcs.append addressof draw_image_1
    funcs.append addressof draw_image_2
   funcs.append addressof draw_image_57

end sub

and later you can just

   Sub drawIMAGE( imgKey as integerInt)

         dim a_delegate as no_arg_delegate

         a_delegate = funcs(imgKey)

   end sub

Thanks… that provides something to think about… the question is, will any of those be “faster enough” to make the effort worth while. :slight_smile:

I think it would be because you’re avoiding logic gates and the comparison of potentially 57 objects, before the correct function is called.

When working with CIKL, any kind of logic gate really slows down shader performance. So you have to get creative.

The jump table should be measurably faster since
It certainly is in Xojo code and many other languages

I like your solution. Technically you are still making a decision at draw time but it should be considerably faster than a case statement for routing (even if you optimize by putting the most common / likely cases first) and there’s no overhead for late-bound tricks. Even “wasting” an element zero is a good thing because you’re saving a subtraction on each call to draw an image.

Yeah jump tables are immensely useful esp where you can precalculate values ahead of time and then just directly index into a tablee of values

It was one of many q’s asked many many years ago in interviews for coding
Write a function to turn all ASCII characters into their upper case variant

  1. use whatever code you want
  2. no if statements (fine you change to a switch)
  3. no if, select case, switch etc <<<< JUMP TABLE !!!

Seems to implement such a thing in Swift requires ObjC code bound to Swift, and it is not a recommended practice, since Swift considers the use of pointers to be “unsafe”

Sigh… yeah the msgSend API is Objective-C… Apple Developer Documentation

I found this article, I don’t think it helps, but I’ll share it incase it does inspire something. Objective-C vs Swift messages dispatch