Are ternary statements faster than if/then/else statements in javascript?
Asked Answered
L

5

9

I see a lot of:

var something = (is_something_true()) ? 3 : 4;

in javascript. Is this faster than

var something;
if (is_something_true()) {
    something = 3;
} else {
    something = 4;
}

Or is it written concisely for convenience?

Lette answered 6/7, 2012 at 20:4 Comment(1)
In a modern JavaScript runtime it probably makes little difference, but you can always test it and see.Poach
B
7

Please enjoy this -- if difference is statistically valid then the result (true or false) also matters -- clearly this is just other stuff on the machine having an impact on browser performance:

Here is the link

different results!

There is a fundamental difference between the two, the ternary statements are expressions and not flow of control. If there is a case where someone writes it as a ternary expression instead of a standard if / than / else, when both would work the same they are (in my opinion) making the code harder to read without good reason.

In terms of speed there should be no difference. Unless you are using a really bad javascript implementation. The slowest part of both statements is the branching.

Bacteriology answered 6/7, 2012 at 20:10 Comment(4)
Nice answer! esp. the ternary statements are expressions and not flow of control second thing, at the end you've mentioned The slowest part of both statements is the branching .. can you please elaborate more or give some insight on this ? what does it mean when you say branching ?Whicker
btw, I got something here docs.oracle.com/javase/tutorial/java/nutsandbolts/branch.htmlWhicker
@agpt That link is not really what is at issue. Here is the Wikipedia explanation which is much better than I could ever do in a comment: en.wikipedia.org/wiki/Branch_(computer_science)Bacteriology
link not working in Safari 12.0? I mean the link does but at the top of the page no graphs rather "something went wrong"Brannen
M
4

You should write for readability first and tiny micro-optimizations one-hundred and fifty-second. The first form is easier to read in many cases and there probably isn't much of a difference in performance one way or the other.

(Even if you disagree and think the second form is easier to read, asking about the relative performance difference is still the wrong question.)

Moustache answered 6/7, 2012 at 20:13 Comment(8)
Ah, but readability is really hard to define. To me (and @Hogan, apparently), the second version is much easier to read; it seems more like human language.Lette
My employer agrees with you both and prohibits the use of the ternary operator. But that's just, like, your opinion, man. I don't find it harder to read at all and have never been able to figure out why so many people do.Moustache
Your employer does not agree with me. There is a place for the ternary operator, as an operator not as a flow of control. He/She should allow you to use it when appropriate.Bacteriology
Yes, the ternary if/then/else operator is a bit ridiculous, especially when used in inconsistent ways to make code messy, and pyhton does not have it because it like the ++ operator is redundant and potentially confusing. However, there are some cases where you might want say, long chained ternary if/then/else operators to check multiple conditions and set a value, and it might even look neat and be readable if used appropriately.Brannen
Being an independent hobbyist coder, I don't really follow coding conventions and do whatever looks best and mostly try to keep my coding style consistent through individual projects, so there are plenty of cases where I might use it for fun. If it were more efficient than flow, it could be extremely useful in projects involving nested for-loops running some lines of code thousands of times per frame, as the speed multiplier would stack resulting in a noticeable decrease in lag. Even though the data seems to point to this not being the case, it is still more compact and great for code golf andBrannen
(I keep hitting the character limit) and besides may be better for cases where you are returning a value and do not want to have an if/else statement which may be bulky and even, ironically, harder to read if (condition) { return x; } else { return 0; } vs return condition ? x : 0;Brannen
@Brannen -- I don't like either of your examples for clear code -- I think the best "self documenting code" is something like this : int finalStatus = condition ? x : 0; return finalStatus; This code is clear -- here is the line where I calculate the final status. I'm going to return the final status. When the way to calculate the final status changes you change the line that calculates it. you don't have change other parts. If you are returning something other that final status then you should use a name that reflects what you are doing.Bacteriology
@hogan well I do. or maybe your right mabe they're messy. idk. for that specific case you could also use another less used operator, the bitwise logical or condition | 0 but only if condition is a number and greater than zero. Also works if condition is undefined, or null in JavaScript I think. very useful for efficiently turning undefined or null into 0 to prevent NullPointerException etc. wait thats JAva nvmBrannen
P
4

Here is the statisitics:enter image description here

After multiple tests and observations, it can be concluded,that the most cases the ternary operator(?:) is slower,than if/else.

Proportional answered 6/7, 2012 at 20:17 Comment(11)
Yes, in an entirely insignificant and imperceptible way.Moustache
Look here jsperf.com/test-vs-exp for the result of the function (true or false) having a bigger impact.Bacteriology
@Bacteriology But the most cases if/else wins the race.Proportional
@Proportional - That is not what I see right now, only on firefox is that true, and there were only two firefox tests. A lot more tests are needed to say anything for sure.Bacteriology
@Bacteriology Even in your posted image,it is seen that if/else wins.Compare flow false with tri false, and flow true with tri true.Proportional
@Proportional - Don't trust these results, they can be biased, go to the test page and run, for the tri tests move the mouse a lot (more effect if you move it over the links that fire events), keep the mouse still for the the if then tests -- see for yourself you can change these minor results easy.Bacteriology
@Engineer: In Opera, when given a true condition, the ternary wins. The ?: and if/else are syntax. What matters is implementation. It's not all that good to draw such an absolute conclusion from one test, tested in one browser.Willodeanwilloughby
@amnotiam I have changed my 'absolute' conclusion.Proportional
@Bacteriology link goes to page but says "something went wrong" at top of page and shows no graphs in Safari 12.0...Brannen
@Brannen -- indeed. It seems something is wrong with jsperf. Maybe it will come back, maybe not.Bacteriology
oh :( hope they fix itBrannen
A
1

Yes, there is negligible difference between the two.

However the difference is so small that it doesn't matter which one you use (I prefer if/else) because they help in readability which would save you a lot of time if someone is going through your code or maybe you yourself are maybe after say 3 months or so.

For those people who want to check the difference try this code:

// declarations  
var num1 = 10, num2, i = 0, startTime, endTime, x, y;

// start timer
startTime = Math.floor((new Date()).getTime());

for(; i < 1e8; i++) {
  // first part if /else
  if(x == 10)
    y = x;
  else
    y = 0;

  // second part ternary
  y = (x == 10) ? x : 0;
}

// end timer     
endTime = Math.floor((new Date()).getTime() - startTime);
document.write("Time taken " + endTime + " ms");  

Note: Comment one of the part and execute the code and run the loop for large number of iterations (above code millions of iterations).

Tip: Try running the loop multiple times to get average.

Analogue answered 24/10, 2017 at 18:13 Comment(0)
V
0

I modified this test that Zaheen made to make it run the test 50 times on both if...else and ternary and automatically output a list of the results and averages of each one into the console, and it consistently gives me a slightly faster speed for the ternary than the if...else when I run it in the console in Microsoft Edge.

    var lista = []
    var listb = []
    var ib = 0
    var ic = 0
    for(; ib < 50; ib++) {
    // declarations  
    var num1 = 10, num2, i = 0, startTime, endTime, x, y;

    // start timer
    startTime = Math.floor((new Date()).getTime());

    for(; i < 1e8; i++) {
      // first part if /else
      if(x == 10)
        y = x;
      else
        y = 0;/*

      // second part ternary
      y = (x == 10) ? x : 0;*/
    }

    // end timer     
    endTime=Math.floor((new Date()).getTime() - startTime)
      lista.push(endTime)
    }
    for(; ic < 50; ic++) {
      // declarations  
      var num1 = 10, num2, i = 0, startTime, endTime, x, y;

      // start timer
      startTime = Math.floor((new Date()).getTime());

      for(; i < 1e8; i++) {/*
        // first part if /else
        if(x == 10)
          y = x;
        else
          y = 0;*/

        // second part ternary
        y = (x == 10) ? x : 0;
      }

      // end timer     
      endTime=Math.floor((new Date()).getTime() - startTime)
      listb.push(endTime)
    }
    var averagea = 0
    lista.forEach(v=>averagea+=v)
    averagea/=lista.length
    var averageb = 0
    listb.forEach(v=>averageb+=v)
    averageb/=listb.length
    console.log({ifelse: {times: lista, average: averagea+" ms"}, ternary: {times: listb, average: averageb+" ms"}})

Here are the results that I got from the console in Microsoft Edge:

{
    "ifelse": {
        "times": [
            166,
            143,
            148,
            161,
            151,
            138,
            135,
            148,
            150,
            154,
            150,
            148,
            143,
            140,
            150,
            141,
            157,
            140,
            150,
            152,
            185,
            223,
            198,
            160,
            147,
            144,
            156,
            173,
            154,
            170,
            152,
            165,
            150,
            150,
            147,
            146,
            136,
            146,
            147,
            146,
            143,
            146,
            140,
            141,
            153,
            147,
            143,
            136,
            146,
            156
        ],
        "average": "152.22 ms"
    },
    "ternary": {
        "times": [
            144,
            148,
            159,
            139,
            138,
            144,
            143,
            148,
            137,
            142,
            152,
            147,
            147,
            157,
            146,
            141,
            144,
            142,
            150,
            135,
            147,
            149,
            144,
            139,
            156,
            138,
            144,
            148,
            142,
            143,
            142,
            141,
            146,
            143,
            142,
            143,
            140,
            137,
            139,
            149,
            144,
            137,
            139,
            153,
            138,
            140,
            149,
            151,
            141,
            139
        ],
        "average": "144.12 ms"
    }
}
Vitellin answered 5/4 at 23:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.