A better way to make selections, faster than IF THEN ELSEIF ELSE?

wapo54001

Senior Member
I think I remember fairly recently reading a thread in which someone said that method X executes faster than IF THEN ELSEIF selection. I looked at the manual and it seems to me that the only thing it could be is the SELECT CASE routine. Am I right or is there a better way?

I'm revisiting a project I completed more than five years ago and trying to update and streamline my code as much as I know how. This is my first step because there are a lot of IF THEN ELSEIF ELSE routines in the code and if there is a faster alternative it seems like changing it would make a difference.

I remember long ago there was a document or two floating around that gave advice on the best way to do a variety of things efficiently. I wonder if they have been maintained or updated? I can't seem to find anything like that now.
 

lbenson

Senior Member
well_it_depends.jpg
In some circumstances, "ON offset GOSUB address0, address1, ...addressN" can improve speed.
With SELECT CASE (and IF THEN ELSEIF ELSE), putting the most likely conditions first can improve performance.
 

inglewoodpete

Senior Member
If it is just a value substitution then LookUp and LookDown are among the fastest to execute. If you need to branch, then If/Then are the next fastest.
 

AllyCat

Senior Member
Hi,

Yes, it depends on the nature of the decisions (branches), but if you have a fairly structured list then the ON ... GOTO is significantly faster after about four.elements. Basically, a single IF .... THEN executes in about 1ms (at 4 MHz) so a four-way branch would take 2ms, and the ON <index> GOTO takes 1ms (assuming you're starting with an index of 0) plus 200us for each label in the list (i.e. a delay range of about 1.2 - 1.8ms). Note that the LOOKUP command has very similar delays, but always "compares" all entries in the list (so 4 would take about 1.8ms) whislt the ON .. GOTO "bales out" when the condition is met.

Generally, adding an "ELSE" to an IF .. THEN, or using the SELECT ... CASE structure is significantly slower. I've posted a Code Snippet to measure execution times, which links to my earlier measurements, and used the ON ,,, GOTO structure with success to decode a 96-way "tree" in a recent "Finished Project" .

Cheers, Alan.
 

wapo54001

Senior Member
First, thank you all for the information, clearly it's not as simple as I understood it to be.

Second, aw heck, this is above my pay grade. I'm going to keep it as it is since it works. I was already old when I made my first post in this forum back in 2006, I am now definitely too old to mess with figuring out when to use which selection routine!
 

AllyCat

Senior Member
Hi,
.. it's not as simple as I understood it to be....... I'm going to keep it as it is since it works.
Yes, there's a lot to be said for "If it ain't broke don't mend it." But for anyone who is attempting to write "efficient" program code, I suggest three quite simple "rules" (with optional refinements in italics):

1. If you have a "list" of options, for example a "menu" structure, then use the ON <index> GOTO ... with "meaningful" labels to indicate what is to happen. Ideally, start the "index" at zero (which computers like), but if you want to count like a human, (upwards from one), then starting each list with a "Nul" (i.e. zero) is easier and faster than decrementing (i.e. subtracting 1) from the Index.

2. If you have a group of similar functions that use different numerical values (for input or for output), then use just one block of code with a LOOKUP (or a LOOKDOWN) command. This is more efficient than a SELECT ... CASE structure for a simple (linear) list, or consider a mathematical expression for more complex relationships (e.g. logarithmic or exponential).

3. If all the "decisions" (or branches) have little or nothing in common, then the IF .... THEN {GOTO} label structure is potentially more efficient (than using an "ELSE {IF}"). If there is a large number of alternatives, ideally arrange them as a "binary tree" (i.e. each branch splits again {and again}), but if this is not possible then separate off each "hit" via the THEN {GOTO} path (again with a meaningful name), leaving the remaining options to "fall through" (which is faster) into the next IF.

The reasoning behind this strategy is that the base PIC (and I suspect PICaxe Basic) ONLY has a (conditional) "GOTO" (or "jump") instruction; the more "advanced" structures (ELSE {IF}, SELECT ... CASE) are built by the Program Editor from the basic IF and GOTO elements. To put numbers on this, the (unconditional) GOTO and the IF <Not true> (i.e. fall through) paths take about 800 us (with a 4 MHz SETFREQ) whilst the IF <True> THEN {GOTO} (branch) takes about 1200 us (i.e. 50% longer). The Program Editor can really only "guess" at which are the more critical paths, whilst the (human) programmer may actually "know" what needs to be done most efficiently.

Cheers, Alan.
 
Top