Jump to content

questions: else if, If


chriz Breck
 Share

You are about to reply to a thread that has been inactive for 4715 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

Righto so straight to the point here is the case an object is listening for a message and lets say it hears it. Would one want to do a bunch of 'if' or one 'if' followed by 'else if'. This is sorta a general scripting question I guess no matter the language but I never learned why I would do one over the other. They both seem to work. Example below

Message incoming ->

If (msg ==  "1") Do stuff

If (msg == "2") other stuff

if (msg == "3") more stuff

 

OR

If (msg ==  "1") Do stuff

else If (msg == "2") other stuff

else if (msg == "3") more stuff

 

 

Why would I do one over the other?

 

Thanks for the help.

-chriz Breck



 

Link to comment
Share on other sites

In the first case, where you have ALL ifs, every single one of them is executed.  That is, the one that says if (msg == "2") will be executed regardless of what the outcome of if (msg == "1") is.  In the second case, the tests after the first one are only executed if the first one fails.  The first way wastes effort in this example, because it executes unnecessary tests after it finds one that succeeds.   The general rule is "only test what you need to."  This is especially important if you have a stack of conditions and the outcome of a later one would give you a different result if it and a previous one BOTH evaluated to TRUE.

ETA:  Dumb, dumb.... I meant "first" and typed "second."  Fixed.

Link to comment
Share on other sites

The second way, meaning the 'else if' ones?

 

Wouldnt that be more efficent than the string of 'if's?

 

Because the way I see it

 

If (msg ==  "1") Do stuff                                           Fails Check next one

else If (msg == "2") other stuff                               Passes skip next one

else if (msg == "3") more stuff                               Skipped

 

Im not sure if that is what you were already saying and I just misread but I just want to make sure.



Link to comment
Share on other sites

the first structure is used when multiple condition could be met to be sure and capture them all, the second will only go through to the first matching condition... neither is optimal to the situation, but the if/else version is preferable, since it will skip all tests after the first successful one.

it *could* be optimal if the earlier tests are more likely to be true than the later ones.

if all options are equally likely, then a binary tree is more optimal, which is a special way of building if/else statements so that all options take the same number of tests to get to, and no tests that are not needed are performed.

 

the easiest way to build binary trees for text options is to index them in a list, and find the index that matches. once you have the index your check the highest possible bit with an if else, then in each of those choices, test the next highest bit, and so on, until you get to the lowest bit which tell you which code to run... below is an example of 4 actions, sorted into a binary tree

iteger vIntChoice = llListFindList( ["a", "b", "c", "d"], msg );if (~vIntChoice){ //-- ignore items not found in our list    if (0x2 & vIntChoice){ //-- test the second bit        if (0x1 & vIntChoice){ //-- test the first bit            //-- you chose "d" (0x2 + 0x1 = 3, the fourth index)        }else{            //-- you chose "c" (0x2 + 0x0 = 2, the third index)        }    }else{        if (0x1 & vIntChoice){            //-- you chose "b" (0x0 + 0x1 = 1, the second index)        }else{            //-- you chose "a" (0x0 + 0x0 = 0, the first index)        }    }}

 and there's the same thing formatted a bit differently for ease of reading the options

iteger vIntChoice = llListFindList( ["a", "b", "c", "d"], msg );if (~vIntChoice){    if (2 & vIntChoice){ if (1 & vIntChoice){        //-- you chose "d" (0x2 + 0x1 = 3, the fourth index)    }else{        //-- you chose "c" (0x2 + 0x0 = 2, the third index)    }}else if (1 & vIntChoice){        //-- you chose "b" (0x0 + 0x1 = 1, the second index)    }else{        //-- you chose "a" (0x0 + 0x0 = 0, the first index)    }}

 

Link to comment
Share on other sites

I wouldn't go as far as using binary trees. To me, optimization in LSL rhymes with "the least code as possible". Still, I agree with Void that you should avoid manipulating strings if you're not directly interested by the result. Use llListFindList() and work with integers. Much faster!

As for "else if" vs. "if", there is another possibility: To use the keyword "return". I find it very useful. It works as well in an event as in a function --with or without returned value.

some_event(some_params)
{
integer choice = llListFindList(list_of_choices, [param]);
if (choice == something) { do_stuff(); return; // Skip the rest! } if (choice == something_else) { do_more_stuff(); return; // Skip the rest! } if (choice == last_choice) { do_something(); // return; // Useless here. }
}

 Some zealots will disagree and chant very loudly "Everything should have only one entry and one exit" but you just have to ignore the voices that don't come from inside your head... :P




Link to comment
Share on other sites

Are you sure its much faster? I've done tests before and its usually slower, I've found, and then since you're using trees + the list stuff it takes up even more memory.

 However, it can take up less memory if the list is a local list since local lists take up less memory per character than local strings.

Link to comment
Share on other sites

fall through for if is only optimal if multiples are possible, because they run all tests before and after they get less efficient the larger they get. they are whoever the smallest in code size, largest test waste (all options tested)

fall through for if/else is only optimal if tests that are more likely to be true are first, because it will run all tests betore the one that is true. they get less efficient the larger they get, middling code size, and test waste (all previous options tested)

Binary trees don't begin to really shine until you get over 4 items, at which point they surpass all the others for roughly equal likelihood paths. they get more efficient the larger they get, only adding one test processed for each power of two more options. largest code size, smallest test waste (none).

  • Like 2
Link to comment
Share on other sites


Void Singer wrote:

Binary trees don't begin to really shine until you get over 4 items, at which point they surpass all the others for roughly equal likelihood paths. they get more efficient the larger they get, only adding one test processed for each power of two more options. largest code size, smallest test waste (none).

Except you have to run the list function which also gets proportionally slower as the list gets longer, and as I said I did test a straight set of if/else-ifs versus a list, and I think it was around a 16 command long list, and the straght if/else-ifs were faster.

And yes I did use a binary tree.

 

Link to comment
Share on other sites

in lsl, yes list processing is a slow operation, but the tree structure itself is still more efficient, AND faster (not necessarily the same things, and I didn't say the latter till now). not all data requires a list find, and some could require extended string processing which is even slower. of course we're talking microseconds difference even in LSO.

considering that I do active searches with conversion on lists of ~600 long string elements up to 1/sec without any noticeable effects, I doubt it'll make a noticeable difference. On the plus side of that tradeoff you get the ability to to separate the command path out, and even manipulate it on the fly, which makes the code more reusable. it also prevents duplication errors, compared to the if only version.

that said, for 4 item text commands, it really isn't going to make a difference one can notice no matter how it's written. but the op wanted to know the difference between the structures.

Link to comment
Share on other sites

... and just to be completely different; maintainability.  The processing that's done once the specific operation is identified can be long, making it hard to find a specific one through pages of code.  As such I always order options not by their likely frequency but alphabetically (and use if ... else if ... unless more than one condition can be met).  I also arrange global and local variable declarations and event-handlers the same way.

Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 4715 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...