0

I'm currently trying to squeeze every last millisecond from a JavaScript program that is fired on an event listener at a rate of 10x per second. I'm trying to remove all cruft. When an if block's sole purpose is to return something if true, is there any advantage to following with else if or else, or am I right in thinking that I forgo else.

eg.

// with else
function withElse () {
    if (foo) {
        return foo;
    } else if (bar) {
        return bar;
    } else {
        return baz;
    }
}

// without else
function withoutElse () {
    if (foo) return foo;
    if (bar) return bar;
    return baz;
}
seyDoggy
  • 140
  • 2
  • 8
  • I believe you are correct. However, this is very easy to test and be sure once and for all. – Shomz Sep 13 '14 at 13:41
  • Personally I think that `else` after a block with a `return` is kind-of an anti-pattern. Then again some people think that `return` in the middle of a function is a bad thing. – Pointy Sep 13 '14 at 13:42
  • 1
    possible duplicate of [What is better? if..else or multiple simple if](http://stackoverflow.com/questions/4139496/what-is-better-if-else-or-multiple-simple-if) – Gergo Erdosi Sep 13 '14 at 13:42
  • I much prefer the latter for readability. – rybo111 Sep 13 '14 at 13:42
  • http://stackoverflow.com/questions/4139496/what-is-better-if-else-or-multiple-simple-if, http://stackoverflow.com/questions/17429893/if-else-vs-if-for-performance-and-readability, http://stackoverflow.com/questions/1820839/using-return-instead-of-else-in-javascript – Gergo Erdosi Sep 13 '14 at 13:43
  • 1
    The `else` is going to cost a microsecond or two at compile time, other than that, no performance impact whatsoever. I'm sure there are more interesting things to optimize in your program. –  Sep 13 '14 at 13:45

2 Answers2

4

No, there isn't. You may choose to have it for clarity, but it's not required (and you may choose not to have it to avoid redundancy; it's totally a style choice).

(Similarly, you may choose to always have the block — {...} — for clarity, but it's not required either.)

Neither of those things matters from a performance standpoint.

There's a third choice to consider:

function withElse () {
    var rv;

    if (foo) {
        rv = foo;
    } else if (bar) {
        rv = bar;
    } else {
        rv = baz;
    }

    return rv;
}

More verbose, but it has the advantage that the function exits in a single location, which can be useful for debugging. It has the disadvantage, of course, of...being more verbose. :-)

On a simplistic engine, that third choice may have a tiny, tiny performance penalty; on an optimizing engine such as found in modern browsers, I very much doubt it does.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • Or `return foo ? foo : bar ? bar : baz;`, or `return foo || bar || baz;`. –  Sep 13 '14 at 13:48
  • @torazaburo: LOL yeah, if you want to go the other way on readability/debugging (your first example, not the second). ;-) But I was sort of assuming the conditions and return values weren't actually the same thing... – T.J. Crowder Sep 13 '14 at 13:48
  • 1
    @torazaburo don't forget `switch {case foo: return foo; case bar: return bar; case baz: return baz;}` – Paul S. Sep 13 '14 at 14:13
  • 1
    @PaulS.: You meant `switch (true) {...`, but yeah, there's that too! :-) (Also `default` rather than `case baz`) – T.J. Crowder Sep 13 '14 at 14:17
  • @PaulS: Love the switch. –  Sep 13 '14 at 14:27
  • 1
    Unfortunately, a truthy value will not match the `true` in `switch (true)`. So needs to be `switch (true) {case !!foo: return foo; case !!bar: return bar; default: return baz; }` –  Sep 13 '14 at 14:34
0

Answering your question, there's no difference between the two programs and you can leave it out if you want.

But, as @torazaburo said "The else is going to cost a microsecond or two at compile time". But, for what I know, it doesn't make any difference at run time, so even if you're calling this function 1000x per second you aren't optimizing anything.

if (foo) {
    return foo;
} else if (bar) {
    return bar;
} else {
    return baz;
}

Will be compiled (by a stupid compiler) to something like this (but in assembly):

1. ifnot (foo) goto line 4;
2. return foo;
3. goto line 9;
4. ifnot (foo) goto line 7;
5. return foo;
6. goto line 9;
7. ifnot (foo) goto line 9;
8. return foo;
9. 

Against:

if (foo) return foo;
if (bar) return bar;
return baz;

That would be:

1. ifnot (foo) goto line 3;
2. return foo;
3. ifnot (foo) goto line 5;
4. return foo;
5. ifnot (foo) goto line 7;
6. return foo;
7. 

The performance is the same! (I also prefer the second for readability!)

Ps: If you think I'm saying anything wrong, please correct me

t.pimentel
  • 1,465
  • 3
  • 17
  • 24