Jump to content

if ... else if --vs-- if .. return; if .. return;


primerib1
 Share

Recommended Posts

Would love some perspective / thoughts on this.

Compare the if .. else if structure:

if (condition1) {
    // lotsa things
}
else if (condition2) {
    // lotsa things
}
// and so on

with the if..return; if..return; structure:

if (condition1) {
    // lotsa things
    return;
}
if (condition2) {
    // lotsa things
    return;
}
// and so on

What are the pros & cons for each?

I have been doing ladder comparisons like the latter; should I use if..else if instead?

EDIT: I might have to add : There is nothing after these ladder comparisons. So really when a branch is taken, there is no need to return to the 'trunk', so to speak.

Edited by primerib1
Link to comment
Share on other sites

22 minutes ago, primerib1 said:

EDIT: I might have to add : There is nothing after these ladder comparisons. So really when a branch is taken, there is no need to return to the 'trunk', so to speak.

Theoretically, the "else-if's" if your first example never run once an "if" is found with the matching condition.

Kind of obviously, the first example won't work if your function needs to return a value. (The main trunk in the first example would need a "last chance" Return statement to return a value, or you'd get a compiler error.)

Link to comment
Share on other sites

If there's no logic after the if-checks, then there is no measurable difference. Stuff like this could considered a micro-optimization (or non-optimization), since there should be no case where one of these makes the code faster, especially in a high-level language like LSL. (You can find similar discussions in other languages.)

The upside is that you can freely pick whichever you prefer. 🙂 I'd probably be more partial to the if-else-if chain because it reduces the chance that I'll forget to add a return at the end of every if.

At the same time, I do use the if-return style a lot as a form of early-exit, when I know no more work needs to be done after that point. (But in this context there is always more code after the return.)

  • Thanks 1
Link to comment
Share on other sites

50 minutes ago, Love Zhaoying said:

Are you analyzing based on just a few conditions, or a lot of conditions?

One of my scripts has like 8 conditions to check.

34 minutes ago, Love Zhaoying said:

Theoretically, the "else-if's" if your first example never run once an "if" is found with the matching condition.

I was thinking something like:

listen(...) {
    if (...) {
        // things
    }
    else if (...) {
        // things
    }
    // ... and 6 more ...
    // closing / cleanup / etc
    ...
}

Though in my case, there is no "closing/cleanup" part

10 minutes ago, Wulfie Reanimator said:

If there's no logic after the if-checks, then there is no measurable difference. Stuff like this could considered a micro-optimization (or non-optimization), since there should be no case where one of these makes the code faster, especially in a high-level language like LSL. (You can find similar discussions in other languages.)

Awesome, cool!

Link to comment
Share on other sites

31 minutes ago, Wulfie Reanimator said:

The upside is that you can freely pick whichever you prefer. 🙂 I'd probably be more partial to the if-else-if chain because it reduces the chance that I'll forget to add a return at the end of every if.

I've had cases with a gazillion "if-else" checks, where I finally added "range checks" to limit the total if/else's checked:

if (a>=1 and a<5) {

  if (a==1) {}

  else if (a==2) {}

 ..

}

else if (a>=5 and a<10) {

  if (a==5) {}

  else if (a==6) {}

 ..

}

etc.

Thoughts?

Link to comment
Share on other sites

Yeah the only real optimization you can do is re-order them so that the "most likely" branches are highest in the list (also a fairly micro-optimization).

if your if-conditions and actions have some sort of correspondence, you can sometimes re-organize it into a non-conditional, but that's only possible in specific cases.

  • Like 2
Link to comment
Share on other sites

6 minutes ago, Love Zhaoying said:

"range checks"

Probably unnecessary unless

  • The ranges are semantically helpful (for example, testing HTTP return codes, grouping 400's together makes sense)
  • Some snippet can be 'factored out' of like categories
  • You have hundreds, not handfuls of tests. (in most cases you're probably doing something wrong if you need that many conditionals)

also, for range checks, you only need to check one direction:

Quote
integer i;
if(i>100)
{	// too big
}else if(i>90)
{	// (90,100]
}else if(i>80)
{	// (80,90]
} //...
// alternatively
if(i<0)
{	// negative
}else if(i<10)
{	// [0,10)
}else if(i<20)
{	// [10,20)
}

The fact that a conditional chain didn't branch earlier, changes the context of later conditionals.

 

Link to comment
Share on other sites

2 minutes ago, Quistess Alpha said:
  • Some snippet can be 'factored out' of like categories
  • You have hundreds, not handfuls of tests. (in most cases you're probably doing something wrong if you need that many conditionals)

also, for range checks, you only need to check one direction:

Quote
integer i;
if(i>100)
{	// too big
}else if(i>90)
{	// (90,100]
}else if(i>80)
{	// (80,90]
} //...
// alternatively
if(i<0)
{	// negative
}else if(i<10)
{	// [0,10)
}else if(i<20)
{	// [10,20)
}

The fact that a conditional chain didn't branch earlier, changes the context of later conditionals.

Expand  

 

Interesting approach, with "one direction" -  that had not occurred to me!

In my case, I had dozens of comparisons - probably more than 50.  Reducing it to "ranges" made sense to me.

 

  • Like 1
Link to comment
Share on other sites

I prefer if .. else, mainly as I can do this kind of BS

list TOKENS = ["help","target","pewpewpew"];

integer pointer = llListFindList(TOKENS,[current_token]);
integer i;
if (pointer == i++) {
    // help - list the commands and how to use them .. 
}
else if (pointer == i++) {
    // target - target an avatar passed with command
}
else if (pointer == i++) { 
    // pewpewpew - if we have target, spam with lasers and fire
}
Edited by Coffee Pancake
  • Thanks 1
  • Haha 2
Link to comment
Share on other sites

You do realise that we're almost next door to the good old days when self-modifying code was allowed?

I remember having to track down a problem for somebody when their developed code stopped working when released to production. Turns out they had written a bit of Z80 code that stuffed a value into an address in the actual code segment where the byte they modified was an instruction to either increment or decrement the HL register pair, which was then treated as an address to jump to, so the code would effectively take one of two branches. It worked fine in the development environment where everything was in RAM, but it stopped working when burnt into ROMs.

  • Like 2
  • Thanks 1
Link to comment
Share on other sites

3 hours ago, Love Zhaoying said:

I love it when we start to venture into what I call, "unreadable code"!

How many actions can we cram into a single statement? Let's find out!

I've been down this road with C at school because of overly-restrictive mandatory style-guides.

The answer is... Don't. 😞

Edited by Wulfie Reanimator
  • Thanks 1
Link to comment
Share on other sites

2 minutes ago, Wulfie Reanimator said:

I've been down this road with C at school because of overly-restrictive mandatory style-guides.

The answer is... Don't. 😞

It still chaps my tail-fur that people NOW insist on the convention:

if (constant-value == idenfier) - example: if (0==x)

Where were they 40 years ago?!?

Link to comment
Share on other sites

1 minute ago, Love Zhaoying said:

It still chaps my tail-fur that people NOW insist on the convention:

if (constant-value == idenfier) - example: if (0==x)

Where were they 40 years ago?!?

Blame that on C where

if (variable = A_CONSTANT) { do_things(); }

is something totally acceptable, and will even work -- until a certain point.

I'm so glad Python used a totally different symbology; to assign and use the assignment, not only you have to use ":=", you also have to put it inside parens:

if (var := func()) == A_CONSTANT:
    do_things()

No more butter-fingering the equal sign!

Link to comment
Share on other sites

Just now, primerib1 said:
5 minutes ago, Love Zhaoying said:

It still chaps my tail-fur that people NOW insist on the convention:

if (constant-value == idenfier) - example: if (0==x)

Where were they 40 years ago?!?

Blame that on C where

if (variable = A_CONSTANT) { do_things(); }

is something totally acceptable, and will even work -- until a certain point.

Some compilers actually warn you about this, at least with newer C++ / C# / .Net languages.

Good old assembly, where

CMP is compare

LDA/LDX is load

STA/STX is store

and there's no way to confuse them.

Link to comment
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...