If else performance - javascript

I run performance test jsperf for three simple if else statements with same logic:
test if1:
var a = "1";
if (a == "1") {
a = "1"
} else {
a = "2"
}
test if2:
var a = "1";
if (a == "1")
a = "1"
else
a = "2"
test if3:
var a = "1";
a == "1" ? a="1" : "2";
Can someone tell me why test if1 is fastest of three?
The first time i compare test if1 with test if2 and test if1 was faseter. After i check test if1 with test if3 and test if1 was faster again. Now i compare all of them and test if2 was faster.
All three together
tested on Chrome 34.0.1847

Did you run them many times to see if you consistently get the same results?
Even if you do, they're probably a very tiny difference. Such a difference would never make a practical difference in the overall performance of a full system. Trying to optimize through trivial syntax changes like these would be a very bad case of premature optimization which can make your code harder to read, and is a waste of time because it won't give you any real benefits.
Now I hope you understand that your question is actually a "wrong question", but in case you still want an answer as to why the first test performs fastest (if it really does), that would depend on some deep details of the JavaScript engine executing the code. JS engines are very complex nowadays, with huge amounts of optimization, so you can't really tell e.g. what CPU instructions will be emitted for a piece of code. In the next minor update of Chrome, the other tests could suddenly become faster due to some change somewhere in Chrome's JS engine.

There is no meaningful performance difference in your three cases--the difference is on the order of 1%.
Note that in the third case, you are failing to set a to "2", but instead merely returning "2".
The presence or absence of brackets is highly unlikely to have any significant impact on performance, or more likely no impact whatsoever. It's a one-time, parse-time issue. The ternary form, your third case, is in essence logically identical to the first two cases. In fact, most minifiers would turn your cases 1 and 2 into a ternary operator.

Related

What is the main difference between these two loops as a solution to this exercise? (learning javascript)

I am learning JS and came across this exercise:
Write a loop which prompts for a number greater than 100.
If the visitor enters another number – ask them to input again.
The loop must ask for a number until either the visitor enters a number greater than 100 or
cancels the input/enters an empty line.
Here we can assume that the visitor only inputs numbers.
There’s no need to implement a special handling for a non-numeric input in this task.
My solution works and was as follows:
let value;
while (true) {
value = prompt('Enter a number greater than 100', 0);
if (value > 100 || value === '');
console.log(value);
break;
}
The MDN solution was this, and though it is shorter and more simple, it seems to accomplish the same task.
let num;
do {
num = prompt("Enter a number greater than 100?", 0);
} while (num <= 100 && num);
Is my solution still valid? Is the MDN one more proper?
I just want to make sure I am understanding things correctly as I go.
If your solution worked before, I think you probably typed in your solution incorrectly here. I am going to assume you meant to write:
if (value > 100 || value === '') {
console.log(value);
break;
}
Since you're just starting out with JS, you will eventually learn that there will be multiple ways you can handle any given coding problem. It will not always be a good answer/wrong answer type of scenario. Sometimes there are multiple ways to accomplish the same thing.
In this example, the MSN solution is better in terms of readability and possibly safety.
The MSN solution creates a while loop with the exit condition identified in the while statement. This loop will exit when that condition is met.
In your solution, the loop will never exit on it's own, the while() statement will always evaluate to 'true'. This loop needs an explicit exit statement, which you provide with the if() condition.
Your method, although it works, is a little bit less safe in terms of code readability and overall maintenance profile. For example, a future developer could by mistake change the if() condition and inadvertently create a never ending loop.
Or, if the loop contained several dozen lines of code, a developer may miss the if condition, and may add some important code after the if condition (such code would not execute when the exit condition is met.)
Yes, this specific sample exercise is trivial, so the code complexity and readability may not matter. But in large enterprise applications with hundreds of lines of code, such code choices carry serious risks with costly implications.
That said, I'll reiterate - as you learn more about JS, you will often find that there are multiple ways of solving any given problem. Sometimes you do want to create an explicit exit condition through an if() statement, on rare occasions you will want to create a never ending loop.
As you explore more complex problems, you will find needs for such solutiosn. So keep learning, keep trying different solutions, and keep asking questions.

JS - If condition with only 1 else, does checking order affect performance?

I was working on a project and this problem popped into my head. I am not sure if there is already a post like this but I have found none.
Let say if I have this:
function checks(s) {
if (s.length == 4 && s[0] == "a") {
//action
} else {
//other action
}
}
checks("a001");
checks("else");
checks("else");
checks("else");
and this:
function checkb(b) {
if (b) {
//action
} else {
//other action
}
}
checkb(true); //Suppose i'm passing these through another function
checkb(false); //so it makes sense for me doing these
checkb(false);
checkb(false);
Since either way the if-statement is going to have to check once of the conditions, if the frequency of the actions are known (e.g. I know that the else part is performed most often). Does checking for "not conditions" make the code run faster or does the checking of "not condition" don't even affect the performance? (Suppose I'm building a complicated node.js server that has many of these type of functions.)
Addition question: Do most programming languages do the same too theoretically?
I was just wondering if it affects the performance (practically or theoretically).
Short answer: No, it does not effect the computation time.
Long answer: Most Javascript engines (Spider Monkey and V8) internally use a Just in Time compiler which will iron over those differences during runtime.
In low level programming languages (read: C/C++ and the ilk), you may gain something if you are able to prevent branch mis-predicts, like in C++ code, but the gain is usually worth it only if you are doing Kernel programming or doing extreme micro-optimizations.
Theoretically, whether it makes a difference or not depends on what kind of compiler you are looking at. If you are looking at a compiler which can learn from code traces, e.g. a Just in Time compiler, then it will make a difference if a certain pocket of code is the hot spot or not. If you are looking at static compilers, it may mean that the compiler may use one less clock cycle in one of the cases (either if or else) by preventing a jmp, but it'll depend on the compiler implementation.

Is one of them quicker: if (!foo < bar) if (foo > bar)?

Out of curiosity. I check whether some string is longer than a maximum specified length:
var name = "This Is a Name";
if (!name.length >= 10)
{
//valid length
}
else
{
alert("Too long");
}
Is this any better / faster (?):
if (name.length <= 10)
I remember that in some languages it's better to write the negation first so is it even betterer (yip, I just wrote that) like so (?):
if (10 >= name.length)
I know that 10 is overlapping in the code - don't mind that. I just want to know if there is any performance / best practice on this.
I almost always use < and <= instead of > or >=. I find that always having the smaller value on the left (when the test succeeds) is quicker to mentally parse. It also makes range tests:
if (0 <= a && a < 10) …
read more like the mathematical equivalent 0 ≤ a < 10.
Performance-wise, I'd be surprised if there was any measurable difference.
This is out of your hands, the interpreter will do whatever it deems right with this. Javascript interpreters might be so advanced nowadays they will optimize this, but more likely those interpreters themselves are compiled with a compiler that will have optimized the translation itself so it was even out of the hands of the person that wrote the interpreter.
So really, if you want a language where you want to control this kind of behaviour, you need asm. Not even in (optimized) C do you really control this.
The only thing you can say with certainty is that n.length > 9 could be marginally faster because it contains less characters so it will be parsed quicker. We're talking nanoseconds, maybe even picoseconds there, though.
Let me just comment on your last example: I am fairly sure that your if(10 >= name.length) convention was started in the era of bad C compiler warnings as an effort to avoid errors of the if(pointer = NULL) { error(); } else { i = *pointer; } type, since the reversed version would make the typo cause a compiler error. This is still surprisingly relevant in jslint-less JavaScript, but I don't think it can affect non-equality comparisons.
For the rest of it, I'm also firmly in the "no difference" camp, even though I haven't experimented, I just can't think of plausible causes where the order would make a performance difference.
If it's not actually the bottleneck of your application, I'd recommend the most readable, not the most performant code - even if there was a slight difference in performance, which I doubt there really is in your case.
In your case, the most easily understandable code piece as far as I am concerned, would be:
if (name.length <= 10)
If you're really intent on getting the most performance out of your code, you would have to write some tests; because speaking generically about this is not possible in most cases, e.g. nearly every JavaScript implementation already will behave slightly different.
Also make sure to check up on "Premature Optimization", e.g. in the wikipedia article on Program optimization (section "When to optimize").

Performance of if-else, switch or map based conditioning

I was wondering about the performances of the following implementations of conditional structs in javascript.
Method 1:
if(id==="camelCase"){
window.location.href = "http://www.thecamelcase.com";
}else if (id==="jsFiddle"){
window.location.href = "http://jsfiddle.net/";
}else if (id==="cricInfo"){
window.location.href = "http://cricinfo.com/";
}else if (id==="apple"){
window.location.href = "http://apple.com/";
}else if (id==="yahoo"){
window.location.href = "http://yahoo.com/";
}
Method 2:
switch (id) {
case 'camelCase':
window.location.href = "http://www.thecamelcase.com";
break;
case 'jsFiddle':
window.location.href = "http://www.jsfiddle.net";
break;
case 'cricInfo':
window.location.href = "http://www.cricinfo.com";
break;
case 'apple':
window.location.href = "http://www.apple.com";
break;
case 'yahoo':
window.location.href = "http://www.yahoo.com";
break;
}
Method 3
var hrefMap = {
camelCase : "http://www.thecamelcase.com",
jsFiddle: "http://www.jsfiddle.net",
cricInfo: "http://www.cricinfo.com",
apple: "http://www.apple.com",
yahoo: "http://www.yahoo.com"
};
window.location.href = hrefMap[id];
Method 4
window.location.href = {
camelCase : "http://www.thecamelcase.com",
jsFiddle: "http://www.jsfiddle.net",
cricInfo: "http://www.cricinfo.com",
apple: "http://www.apple.com",
yahoo: "http://www.yahoo.com"
}[id];
Probably Method 3 and 4 might have almost the same performance but just posting to confirm.
According to this JSBen.ch test, the switch setup is the fastest out of the provided methods (Firefox 8.0 and Chromium 15).
Methods 3 and 4 are slightly less fast, but it's hardly noticeable. Clearly, the if-elseif method is significantly slower (FireFox 8.0).
The same test in Chromium 15 does not show significant differences in performance between these methods. In fact, the if-elseif method seems to be the fastest method in Chrome.
Update
I have run the test cases again, with 10 additional entries. The hrefmap (methods 3 and 4) show a better performance.
If you want to implement the compare method in a function, method 3 would definitely win: Store the map in a variable, and refer to this variable at a later point, instead of reconstructing it.
You can always do a jsPerf test yourself. However, in general a lookup table is the fastest way to access data. That would be (3) in your snippets. Also, switch/case is almost always faster than if-else. So the order for your example would be
(3) -> (4) -> (2) -> (1)
Performance diverges for conditional logic (rather than mere value lookup)
if-else vs switch vs map of functions vs class method dispatch
I think a lot of people come to this question, Performance of if-else, switch or map based conditioning, because they want to know how best to condition logic, as the title implies, rather than simple key-based value lookup.
My benchmark differs from the one in the accepted answer and also corrects a number of its flaws (further explanation at bottom below results table):
Tests branched logic. i.e. conditional execution flow, not simple lookups.
Branches randomly. A random sequence of branch keys is generated in setup. Each approach is then tested with the same sequence.
Branch results aren't predictable. The logic result for each branch are not the same for other branches, nor are they the same for subsequent executions of the same branch.
There are 11 branches. To me this question is more relevant to around that many. If there are much fewer, it doesn't make sense to consider anything other than if-else or switch.
Re-used structures are initialized in setup rather than in the benchmarked code block.
This is what I got on Safari/macOS:
approach
JSBench
if-else
100
switch
99+
map of functions
~90
class method dispatch
~85
I ran the same benchmark again with twice as many branches (22) expecting to see map to gain ground, and I got about the same results (though class method dispatch may be doing slightly relatively better). If I had time I'd write code to generate benchmark code so that I could graph a wide range of branch counts... but alas I don't.
Limitations in the question's sample code and benchmarks in the other answers and comments
The question's own sample code as well as the benchmarks code used in Rob W's answer and jAndy's answer only test value lookup. As expected, for a small set of keys those benchmarks show negligible performance differences; Any significant difference would have been a flaw in the JS engine. They do not demonstrate the issue of conditional logic.
In addition, as some have pointed out, there are other flaws in the benchmark code:
Performance only matters if the conditional logic is executed thousands of times. In such cases one would not reinitialize data structures each use.
The test code takes the same branch every time. This has two problems:
It does not reflect average cost (e.g. for an if-else or switch, earlier branches are cheaper, later are more expensive).
Compile-time or JIT optimization is likely to optimize it away, thereby producing misleading results (because in real code, the conditions would not be so predictable).
Each branch produces exactly the same result each time. And for the Rob W's benchmark, the result is the same as the input!
Of course a map will perform well for this usage. That's what they are designed for!
If you have conditional logic where the logic for each branch produced the exact same result each time, you should consider using memoization.
Just thought I'd add this as a possible consideration. I came across this doing research on this very question... http://davidbcalhoun.com/2010/is-hash-faster-than-switch-in-javascript
It takes different engines and browsers into account.

Javascript toLowerCase() performance versus variable creation

What is more efficient?:
var text="ABCdef";
var lowerVersion=text.toLowerCase();
if (lowerVersion=='abcdef' || lowerVersion=='asdfgh' || lowerVersion=='zxcvbn'){...
or
var text="ABCdef";
if (text.toLowerCase()=='abcdef' || text.toLowerCase()=='asdfgh' || text.toLowerCase()=='zxcvbn'){...
i.e. is variable creation more expensive than running toLowerCase() several times?
Thanks.
This is JavaScript. The answer is going to be: It depends. It depends on what engine you're using, on your data, on the other things in the context, on whether the first or last match matches, on alternate Tuesdays...
But creating variables in JavaScript is very fast. In contrast, the repeated calls version asks the interpreter to make multiple function calls, and function calls (while fast by any real measure) are slow compared to most other operations. The only way that's going to be as fast is if the interpreter can figure out that it can cache the result of the call, which is tricky.
Taking #Felix's performance test and making it pessimistic (e.g., worst case and none of them match) suggests that even Chrome can't optimize it enough to make the repeated function calls not come out worse. I didn't do any comprehensive tests, but Chrome, Firefox, and Opera all came out about 60% slower.
You have an alternative, of course:
var text="ABCdef";
switch (text.toLowerCase()) {
case 'abcdef':
// ...
break;
case 'asdfgh'
// ...
break;
case 'zxcvbn'
// ...
break;
}
All of this is premature optimisation, though, which is bad enough generally but particularly bad with JavaScript and the varying environments in which it runs complicating things.
The better question is: What's clearer and more maintainable?
This is without any doubt that the 2nd implementation will be significantly faster then the 1st one.
It is for sure that when each time text.toLowerCase() will take time like O(n) and there will be 3xO(n) vs O(n)
I have run the test on jsPref.com and the 2nd snippet is 18% faster.
If you are going to refer to the value more than once, store it as a variable: toLowerCase() can be very slow with long strings.
Caching being faster seems logical (3 toLowerCase calls vs one), but the (modern) browsers' scripting engine may well do that for you. I don't think it will matter a lot, if it's a one or few times operation. It may be a question of taste, but I think assigning a variable is more readable/maintainable.
Alternative may be using a Regular Expression for the check:
var text="ABCdef";
console.log(/^(abcdef|asdfgh|zxcvbn)$/i.test(text)
? `${text} is ok` : `${text} is NOT ok`);

Categories

Resources