Let's Make Robots!

Which is faster? select case vs. lookup

So I am working on Walter's head moves which are working quite nicely. There are about 100 different moves stored in EEPROMS and can be cued-up and "played" via a number I have assigned to each move. I.e. I know that numbers 1-10 are all just sorta looking around moves. Move 47 is look quickly down and to the left, then a tilt. Etc. Etc. This leads me to the need to play some of the headmoves back at random. Not just at random, but I want one of the random picks to be part of a catagory of moves. Therefor I have a pack of "fwd looking around", a pack of "looking to the right", a pack of "looking to the left" etc. These numbers when put together, could almost be considered a string or array.

Also in the code, I have one byte (b19) clicking by... I have a inc b19 in many places of the code, mostly in the main loops. This variable is allowed to overflow and does nothing but count up, overflow and count up again. This is my randomizing number. Now, I know there is a random command but it sucks. Even if you seed it or bounce it off the timer, etc, it always has a pattern. With my "always changing variable" approch, I have very good, random results.

Now I might want to send a code to say "play a random fwd head move" and right now, I do this:

ranfwd:
select case b19
case 1 to 23
let b13=1
case 24 to 46
let b13=3
case 47 to 69
let b13=5
case 70 to 92
let b13=7
case 93 to 115
let b13=9
case 116 to 138
let b13=11
case 139 to 161
let b13=13
case 162 to 184
let b13=15
case 185 to 208
let b13=17
case 209 to 230
let b13=19
case >230
let b13=21
endselect
'sertxd ("Ranfwd b13 ",#b13,CR,LF)
return

This returns b13 as a randomly chosen number between 1 and 21 (only odds --not important) and that number is used to call up a move. Also, this method allows me to change probabilty and favor or unfavor one or many moves.

Now I have been thinking of putting these numbers into a lookup table, converting b19 down to a number that could be used with the lookup command and getting my b13 that way. It seems that the lookup table would be faster (and for sure, cleaner to see written-out) but would it really be faster with the extra math at the begining? Is there a rule for calculating speed in these cases?

Did one single thing make sense at all in this whole post?

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

I'm running the x2's, sir! I got 4 times the room I used to have!

--Thanks rik, you da man.... I've got some recoding to do!

And the winner is: TABLE LOOKUPS!

The lookup routine uses ca .37 ms per lookup.
The case/select uses ca 7.5 ms per lookup.
The math routines use on avg 2.9 ms per lookup.

Here's the full output of my test program (running on non-modified 28x2). Times are in increments of 262 ms. Each lookup is performed for every input value ranging 1-254. Times fifty.

timer3=0                                                                                   
timer3=10
store table
baseline empty routine times 50
timer3=37
ctc case/select routine times 50
timer3=396
ctc table lookup routine times 50
timer3=55
rik simple mathfu routine times 50
timer3=173
rik complicated mathfu routine times 50
timer3=173
telefox simplest mathfu routine times 50
timer3=184
and that concludes the lotto numbers for today, stay tuned for Ran & Stimpy after the break

Well, provided you've got the memory spare to store 255 bytes of lookup table then we have a clear winner =)
Solid testing there rik!

input b19 holds all values 0-255 inclusive, evenly distributed
black box holds eleven hidden values: 0-10 inclusive, evenly distributed
output b13 holds eleven values: 1-21 inclusive, odd numbers only, evenly distributed
abracadabra algebra:

b13 = b19 * 11 / 256    ' now ranges 0-10 inclusive
b13 = b13 * 2 + 1        ' now ranges 1 -21, odd, inclusive

Your code example ignores b19 = 0. Is this on purpose? If it's important, write:
b13 = b19 min 1 - 1 * 11 / 255    ' now ranges 0-10 inclusive
b13 = b13 * 2 + 1                      ' now ranges 1 -21, odd, inclusive

Note the lack of parentheses in this picaxe basic math. the position of the "min" operator is crucial, as we learned in your previous post.  On your X2 mcu however, parentheses are welcome.

Your lookup table function could be made faster than the big case statement you've currently got, but the math will need to be fairly simple.

Something along the lines of:
b19 = b13/22
b19 = 2*b19+1 MAX 21
would give you 0-255 -> 1-21, odd numbers only, evenly distributed.