4

Say I have a random number.

Which is more efficient:

if (num == 1) {

} else if (num ==2) {

} else if (num == 3) {

} else if (num == 4) {

} else if (num == 5) {

} else {};

or

if (num == 1) {};
if (num == 2) {};
if (num == 3) {};
if (num == 4) {};
if (num == 5) {};

is there much of a different performance-wise?

Or should I do a switch chain?

AlwaysNeedingHelp
  • 1,851
  • 3
  • 21
  • 29
  • 7
    Yeah, use a switch for this. – Meredith Aug 24 '14 at 18:26
  • possible duplicate of [Is there any significant difference between using if/else and switch-case in C#?](http://stackoverflow.com/questions/395618/is-there-any-significant-difference-between-using-if-else-and-switch-case-in-c) – Meredith Aug 24 '14 at 18:27
  • 3
    Well, they work quite differently (in general). The first example will only test conditions until it found one that resolves to `true`. The second case will evaluate every condition. But since a variable can only hold a single value, there can only be one that is `true` (unless you modify `num` inside of an `if` block. – Felix Kling Aug 24 '14 at 18:27
  • As Felix says, this totally depends. Can `num` change inside the conditions? – Lightness Races in Orbit Aug 24 '14 at 19:26
  • @Meredith: no, not a dupe for C# because that is a compiled language. ECMAScript >V3 will (should) evaluate each case (until a match is found) in runtime, so no 'direct' jump (table)! That's a significant difference. – GitaarLAB Aug 26 '14 at 04:28

5 Answers5

3

If you have a small number of situations that you want to handle separately (and you are using a number to differentiate), then the Switch statement would provide clearer logic to someone (including you) who tries to read or modify your code.

If / else if chains may be mis-perceived later

Successive If statements mean you are constantly checking for a situation you know is wrong

ErstwhileIII
  • 4,829
  • 2
  • 23
  • 37
  • 1
    Can you give an example of how if/else if may be "mis-perceived later"? – Lightness Races in Orbit Aug 24 '14 at 19:03
  • if (num ==1 ) { stmt1; stmt2; if (num1 ==1) { stmt} else if (num2 ==2) { stmt;} else if (num ==2) {stmt3; stmt4; for (int i=1; i – ErstwhileIII Aug 24 '14 at 19:04
  • My point exactly ... such if statements make it rather opaque to see exactly what is being done. You can write valid, equivalent code using successive if statements; if / else if chains and switch statements .. but the switch statement is often the most clear in handling multiple cases. – ErstwhileIII Aug 24 '14 at 19:09
  • I can see quite clearly what is being done; what is not clear is the point you are trying to make with it. Those two pieces of code aren't even _close_ to being "equivalent", so either you're being deliberately misleading at a fundamental level, or I really have missed what it is that you're trying to prove. If I ask you to support "solution X is more misleading than solution Y in this case", then presenting a _totally different program_ that uses solution X with the worst variable naming you can think of ... is not addressing that question. – Lightness Races in Orbit Aug 24 '14 at 19:18
  • I was just trying to demonstrate that a complex set of statements that need to be executed for each case could become confusing when you revisit your code. The chained if/else if mechanism is valid code-wise. – ErstwhileIII Aug 24 '14 at 19:22
  • Yeah, if you write terrible code, but that's not `if`/`else if`'s fault. It's also not the code the OP wrote. The equivalent to _the OP's code_ using `switch` is no clearer. – Lightness Races in Orbit Aug 24 '14 at 19:24
  • My last comment ... I am only pointing out that if/else can be complex to read .. not that you cannot code "correctly" for that situation. – ErstwhileIII Aug 24 '14 at 19:36
3

A bit late to the party, but apart from the other valid answers:
what if you could call your intended subcode (almost) directly (if you have a LOT of options)....

I have a different solution (you were open other options):

var switchArr=[ //skipping 0
, function(){ /* do stuff for 1 */ }
, function(){ /* do stuff for 2 */ }
, function(){ /* do stuff for 3 */ }
]; // you could also set them directly if you have irregular (large) intervals

if(switchArr[num]){
  switchArr[num]();
} else {
  //defaults
}

EDIT: alternatively (expanding on the above concept) using an object (because order does not have to be guaranteed, as array does) and some closure and a simple way to pass num to the handler function:

var switcher=(function(){
  var N, F={
   default: function(){ alert('default function for '+N); }
  ,      1: function(){ alert('doing stuff for '+N);  }
  ,      2: function(){ alert('other stuff for '+N);  }
  ,      5: function(){ alert('I am function '+N);  }
  };

  return function(n){ F[N=n] ? F[n]() : F.default(); };
})();

num=3; switcher(num);  // default function for 3
num=5; switcher(num);  // I am function 5

Depending on use-case one of the above (or a hybrid) could be a better solution. If execution-time is at a prime, don't use the helper-function (that does the check) since that saves a function-call.

EDIT 2:

In the comments is asked for the benefit of this alternative:

Contrary to popular belief (that javascript/ecmascript uses a switch to 'directly jump' to a start-point in a codeblock), the switch statement in modern browsers evaluates the case expressions using the === strict comparison operator (so the expressions must match without any type conversion) in the order in which they (case not default) appear until it finds a value that matches (after which it will 'fall through' until a break or a return when inside a function is encountered or the codeblock ends, hence default can appear anywhere in the codeblock, not only at the end).
This is because the ECMAScript v3 standard allows each case to be followed by an arbitrary expression.

Note (for older browsers) that the switch statement is implemented in JavaScript 1.2, but it does not fully conform to the ECMAScript specification. In JavaScript 1.2, case expressions must be literals or compile-time constants that do not involve any variables or method calls. Furthermore, although ECMAScript allows the switch and case expressions to be of any type, JavaScript 1.2 and JavaScript 1.3 require that the expressions evaluate to primitive numbers, strings, or boolean values.
Source: JavaScript: The Definitive Guide (4th ed)

See the resemblance with an if-chain? The difference is the ability to fall through (until end/break/return).
The amount of comparison work (in an example where you have a LOT of different cases) is thus the same (at least, per spec, not guarantied per interpreter implementation, which wildly varies among versions).

A lot of (generally not frowned upon) optimization involves tweaking code to have a predictable relatively scalable (in regard to the host's capability's) execution-time. In my suggestion (intended to show ways of thinking outsize of the box), you have a small fixed number of steps before your payload executes (something that you can guarantee according to the language-spec).

That leaves 'understandability' which is a tricky question because that is highly related to 'intent' and 'readability', thus opening the can of worms regarding different viewpoints/options/mantra's/best-practices, much of which hold different value (or plain simply don't/shouldn't apply) to 'javascript' (for web-based applications) (in my opinion).
There can be thought of many different approaches using comments etc (or the second example that uses an object) and different coding-styles/patterns that would alleviate initially perceived hindrance of 'clear code'.
After-all, ideally one should have good documented 'raw' ((gzip-)pre-optimized where applicable (you don't want to maintain/debug both raw and 'compiled' code)) code, but send minified (without doc/comments minified var-names etc) code to the browser (in production).

Finally as to performance, again depending on what one is trying to do (and lot of cases are involved), the array version (without helper function) will be smallest and fastest for a range of numerical cases. The object then has its strength in (irregular) numerical intervals and string-based switches. However, as always, one must test (supported target-)hosts/browsers to assess their performance. However up to now, in my experience when dealing with a lot of cases, this one is a winner.

Final note, when dealing for instance with a known set of cases, one wouldn't even need to check if the case exists, let alone need a helper function.. speed for the win (in such a case).

GitaarLAB
  • 14,536
  • 11
  • 60
  • 80
  • 1
    What is the benefit of your approach? I feel a switch statement would be more understandable, and I would expect it to perform better too (but I haven't done any tests) – beetstra Aug 25 '14 at 10:01
  • @beetstra using an enumerated array of function is a great approach worth adapting to. rather than evaluate each condition, the array index allows the processor to simply jump to the memory location of the targeted function. in C/C++ you can ensure this operation is a single operation very easily. even in JS it will be interpreted super fast always. works in practically all modern languages. a common trick coders who have made parsers may recognize – That Realty Programmer Guy Mar 03 '21 at 06:25
1

Generally else-if has better performance than if chain. But to use switch case in such a case would be the best choice.

manas
  • 11
  • 2
1

The efficient way to check is switch statement rather than if,

switch(num) {  
  case 1:  
    do something;
    break;  
  case 2:  
    do something;
    break;  
  default:  
    default do something;  
} 
GitaarLAB
  • 14,536
  • 11
  • 60
  • 80
Syed Arif Iqbal
  • 1,830
  • 12
  • 16
0

The better approach especially for big codes is an if else statement(or even better case). Using multiple if statements leads the pc to do unnecessary calculations. For example:

if (5 > 3){
alert("True");
} 
else{
alert("False");
}

This is a boolean expression.In the above example the cpu checks the if(5 > 3) which returns true and stops(It won't execute or check the else). The same but using multiple if

if (5 > 3){
    alert("True");
    } 
if (5 < 3){
alert("False")}

It will do the same as the previous code but now it will execute 2 calculations instead of one

stranger4js
  • 269
  • 4
  • 15