Is there a performance difference in JavaScript between ">" and "!="? - javascript

Doing a bind for a previous link in a nav. If we're on the first position don't do the same thing for the previous link. I was doing a "!=" not equal to test, but realized it could be a ">" greater than.
Then I thought, is one faster?
if (numberToCheck != 0) {
//doSomething();
}
vs.
if (numberToCheck > 0) {
//doSomething();
}

Performance questions should be resolved via measurement, not speculation.
You can see for yourself here http://jsperf.com/inequality-vs-greater-than. The results of this test (on my computer) vary by browser. Some are faster with inequality. Some are faster with less than. You will likely find much bigger speed differences in other areas of your code.
If you want to test something slightly different than what I put in the test, just add your own test for comparison.

Do you mean like... absolute difference, or "meaningfully different"?
In any case, it would depend 100% on the underlying VM implementation. It might be faster to set a flag and have that flag be the first in an && (for short-circuiting), though, and have the numerical part second.
if (keepChecking && numberToCheck != 0) {
keepChecking == false;
// doSomething();
}
Again, VM-dependent, and I can't believe it'd matter a lot either way.

What about -
if (numberToCheck !== 0) {
//doSomething();
}
Actually, I doubt a human could notice the difference. Plus, each browser js engine might yield different results.

I made a test page at jsperf:
http://jsperf.com/different-from
In Chrome on my MacBook Pro, they are exactly the same.

Related

Why are two calls to string.charCodeAt() faster than having one with another one in a never reached if?

I discovered a weird behavior in nodejs/chrome/v8. It seems this code:
var x = str.charCodeAt(5);
x = str.charCodeAt(5);
is faster than this
var x = str.charCodeAt(5); // x is not greater than 170
if (x > 170) {
x = str.charCodeAt(5);
}
At first I though maybe the comparison is more expensive than the actual second call, but when the content inside the if block is not calling str.charCodeAt(5) the performance is the same as with a single call.
Why is this? My best guess is v8 is optimizing/deoptimizing something, but I have no idea how to exactly figure this out or how to prevent this from happening.
Here is the link to jsperf that demonstrates this behavior pretty well at least on my machine:
https://jsperf.com/charcodeat-single-vs-ifstatment/1
Background: The reason i discovered this because I tried to optimize the token reading inside of babel-parser.
I tested and str.charCodeAt() is double as fast as str.codePointAt() so I though I can replace this code:
var x = str.codePointAt(index);
with
var x = str.charCodeAt(index);
if (x >= 0xaa) {
x = str.codePointAt(index);
}
But the second code does not give me any performance advantage because of above behavior.
V8 developer here. As Bergi points out: don't use microbenchmarks to inform such decisions, because they will mislead you.
Seeing a result of hundreds of millions of operations per second usually means that the optimizing compiler was able to eliminate all your code, and you're measuring empty loops. You'll have to look at generated machine code to see if that's what's happening.
When I copy the four snippets into a small stand-alone file for local investigation, I see vastly different performance results. Which of the two are closer to your real-world use case? No idea. And that kind of makes any further analysis of what's happening here meaningless.
As a general rule of thumb, branches are slower than straight-line code (on all CPUs, and with all programming languages). So (dead code elimination and other microbenchmarking pitfalls aside) I wouldn't be surprised if the "twice" case actually were faster than either of the two "if" cases. That said, calling String.charCodeAt could well be heavyweight enough to offset this effect.

Which Boolean is Faster? < or <=

I'm doing some work involving processing an insane amount of data in browser. As a result I'm trying to optimize everything down to the nuts and bolts. I don't need anyone telling me that I'm wasting my time or that premature optimization is the root of all evil.
I would just like to know if anyone that understands how JS works would know whether or not a lesser than boolean runs faster than a lesser than equals boolean. What I mean by that is, would:
return (i<2? 0:1)
Be parsed and run faster than:
return (i<=1? 0:1)
In this example we're assuming that i is an integer. Thanks.
JavaScript standard desribes the steps that needs to be taken in order to evaluate those expressions. You can take a look at ECMAScript 2015 Language Specification, section 12.9.3.
Be aware that even if there is slightly difference between steps of those two operation, other stuff in your application will have much more influence on performance that these simple operations that you cannot control in JavaScript. For example work of garbage collector, just-in-time compiler, ...
Even if you try measuring time in JavaScript, this will not work as just taking time stamps has much bigger influence on the performance than the actual expression you want to measure. Also the code that you wrote might not be the one which is really evaluated as some preoptimizations might me taken by the engine prior to actual running the code.
I wouldn't call this micro-optimisation, but rather nano-optimisation.
Cases are so similar you'll most likely have a measure precision below the gain you can expect...
(Edit)
If this code is optimised, the generated assembly code will just change from JAto JAE (in (x86) , and they use the same cycle count. 0,0000% change.
If it is not, you might win one step within a selectof the engine...
The annoying thing being that it makes you miss the larger picture : unless i'm wrong, you need a branch here, and if you're that worried about time, the statistical distribution of your input will influence WAY more the execution time. (but still not that much...)
So walk a step back and compare :
if (i<2)
return 0;
else
return 1;
and :
if (i>=2)
return 1;
else
return 0;
You see that for ( 100, 20, 10, 1, 50, 10) (1) will branch way more and for (0, 1, 0, 0, 20, 1), (2) branches more.
That will make much more difference... that might just as well be very difficult to measure !!!
(As a question left to the reader, i wonder how return +(i>1) compiles, and if there's a trick to avoid branching... )
(By the way i'm not against early optimisation, i even posted some advices here, if it might interest you : https://gamealchemist.wordpress.com/2016/04/15/writing-efficient-javascript-a-few-tips/ )
I have created a fiddle using performance.now API and console.time API's
Both the API says how much ms of the time was taken to execute the functions/loops.
I feel the major difference is the result, performance.now gives more accurate value i.e. upto 1/1000th ms.
https://jsfiddle.net/ztacgxf1/
function lessThan(){
var t0 = performance.now();
console.time("lessThan");
for(var i = 0; i < 100000; i++){
if(i < 1000){}
}
console.timeEnd("lessThan");
var t1 = performance.now();
console.log("Perf -- >>" + (t1-t0));
}
function lessThanEq(){
var t0 = performance.now();
console.time("lessThanEq")
for(var i = 0; i < 100000; i++){
if(i <= 999){}
}
console.timeEnd("lessThanEq");
var t1 = performance.now();
console.log("Perf -- >>" + (t1-t0));
}
lessThan()
lessThanEq()
I haven't much difference. May be iterating more may give different result.
Hope this helps you.

Is it possible to rewrite your javascript dynamically

I would like to edit my if else statement in javascript dynamically.
So after one if statement is used, it could be removed. I get this maybe isn't possible but after a search online failed, my curiosity begged me to ask.
For instance:
if (x > 200 && x % 25 === 0) {
doSomething1();
} else if (x > 300 && !inRange) {
doSomething2();
} else if (x > 400 && x % 7 === 0) {
doSomething3();
}
There are eight if else statements within this loop. The loop determines which object to create. There are 2000 objects created over the course of a couple minutes. If on average we reach the fourth statement before it breaks, then there are 8,000 calculations being performed just within this one set of statements.
I want to streamline the script for speed and again, curiosity if we can actually write javascript dynamically without using separate functions etc. After an if statement fails, it is often not required anymore. The next statement could I suppose, include code to remove its predecessor dynamically. This might save 3 or 4 thousand calculations - not huge I know, but worthy of consideration given that there are lots of other things going on as well.
Is there a way to remove them dynamically or does anyone have any tricks or patterns up their sleeves?
Also, even if this is not available in js, what would this be called?
No. And the need for such would indicate poor design.
You should use a conditional expression to determine when which code segment should be run, as you mention. If you pass a certain threshold within your code after which you no longer want a condition to be executed in your loop, why not simply break the loop and have a new code block handling the doSomethingElse clause. If you're using setInterval, that's the point at which you would call clearInterval, and then trigger some new action if necessary. Anyway, running a single (or even a few) simple conditional statement doesn't add much overhead, and isn't likely to be the limiting factor in your optimization anyway.
Ignoring the fact that I doubt this is a bottleneck in modern browsers that JIT the JavaScript (CPUs are very good at predictive branching) as shown because simple number comparison is not going to be expensive even in large iterations with smart predictions once it's compiled.
You can do this by injecting a different function:
checker: function(x) {
if (x > 200) {
doSomething1();
}
else if (x > 300) {
doSomething2();
}
else if (y > 400) {
doSomething3();
}
}
Can be changed to
checker: function(x) {
if (x > 200) {
doSomething1();
}
else if (x > 300) {
doSomething2();
this.checker = smallerChecker;
}
else if (y > 400) {
doSomething3();
}
}
function smallerChecker(x) {
if (x > 200) {
doSomething1();
}
else if (y > 400) {
doSomething3();
}
}
Fundamentally, you simply need to make the behavior injectable, and then you change it however you see fit. Be-it by replacing the function doing the checking outright (the functional way) as I did above, or enabling an object to replace it (the OO way).
Why would you want to remove them dynamically? Altering the code dynamically is unnecessary and a bag of worms that's overdoing it for this situation. You should be using a flag.
I'll answer separately for whether you're trying to skip a large group of if statements, or an individual if statement.
Foreword
As mentioned in the comments on your question, run profiling to make sure you know where your performance problems are!
You mention your aversion to simply using boolean flags to make an if statement not run in your answer. This is fine, and it's what people normally do. This should not be an actual performance concern, and profiling will probably show your performance problems lie elsewhere. If they don't and this boolean flag check is genuinely your bottleneck - you have bigger problems, such as expecting too much from your JavaScript code, or that you didn't use the profiling tool correctly, or misinterpreted its results.
If you're trying to avoid running the body of an if statement, or its conditions, those are a bigger performance concern to you than the boolean flag check itself.
For skipping a large group of if statements
Wrap your bunch of if statements in a condition.
if (runBunchOfIfStatements) {
// all those if statements here
}
When you're past the point of wanting those if statements to run, set the runBunchOfIfStatements flag to false (of course, you should probably pick a more meaningful name than that).
That said, 8 or 9 if statements is a code length issue, and more than likely means nothing at all for performance concerns - unless those if statements happen to involve very intensive checks. If you're worried just because there's a lot of if checks, you're probably looking in the wrong place.
For individual if statements
Say you have only one if statement you want to skip. You had this code in your answer:
} else if (x > 300 && !doneSomething2) {
doSomething2();
doneSomething2 = 1;
}
This is fine. You're just making a tiny check: see the foreword. Look elsewhere for your performance concern. It could be rewritten slightly to more closely follow convention (which I'm about to get to), but in this situation, the change will have negligible impact.
Let's take a situation where there is actually a performance concern here. Suppose that instead of checking x > 300 you're doing something more intensive like calculateSeveralSquareRoots(). Generally, you do take this approach, but you rearrange it like this:
} else if (needCalculations && calculateSeveralSquareRoots() {
// do stuff
needCalculations = false;
}
The difference here is the needCalculations flag comes first, not second. JavaScript's comparison operators have short circuit evaluation. This means that when evaluating a && b, if a is false, b never even gets checked - we already know the result will be false. If the flag comes first, that means calculateSeveralSquareRoots() never gets run, and you save time on the check.
If the flag came second, then you're potentially wasting a lot of time on that function for a condition that might almost always resolve to false anyway thanks to that flag.
So in your original, you could have the flag come before the x > 300 evaluation, just to follow convention. But again... if an if statement like this is a real and significant performance concern for you, then you have bigger issues.
Order them in order of likelihood (so if >400 is most common, check for that first, and if x<200 is next most common, check for that, etc.) The example code is in order of increasing boundaries.
Next, your code doesn't show it and you just imply it, this is in a loop. (And if it isn't a loop, then this isn't a perf issue of interest) You could try fancy loops like Duff's device.
And figuring out what code can be changed to use more native API's is going to make a magical difference, whereas code optimizations like this will likely make only a marginal difference.
If you want it to be dynamic, you could always have a collection of conditions associated with actions and as soon as executed, these gets removed from the collection. However, I doubt it will lead to faster code execution, but you would have to create a jsperf test to know for sure.
DEMO: http://jsfiddle.net/a2ZEj/1/
function doSomethingA() {}
function doSomethingB() {}
var doOperation = (function doOperation() {
var operations = [
{
check: function (someArg) {
return someArg > 100;
},
exec: doSomethingA
},
{
check: function (someArg) {
return someArg > 100 && someArg < 200;
},
exec: doSomethingB
}
];
return function (someArg) {
var i = 0,
len = operations.length,
item;
for (; i < len; i++) {
if ((item = operations[i]).check(someArg)) {
item.exec();
operations.splice(i, 1);
console.log('executed ' + item.exec.name);
return;
}
}
};
})();
doOperation(101); //calls doSomethingA
doOperation(101); //calls doSomethingB
doOperation(101); //does nothing
You can create a method as below and create dynamic conditions
function buildCond(lhv1,rhv1,lhv2,rhv2)
{
var condition1,condition2;
condition1 = condition2 = '';
if(rhv1 !== -1){
condition1 = lhv1 + " == " + rhv1 + " && ";
}
if(rhv2 !== -1){
condition2 = lhv2 + " == " + rhv2 + " && ";
}
return condition1 + condition2;
}
And then call this method with eval to execute
if(eval(buildCond(var1,value1,var2,value2)) === true){
//do stuff
}

Disadvantages of While ! Undefined array loop

According to this JSPerf the While ! Undefined style array loop is ~10x faster in all browsers. What are the disadvantages of this style of loop?
It is actually a bug in the test case, the iterator is not being reset to zero for each test run (i.e., only the first test run rolls the full loop, next runs have the iterator already past the end of the array, thus roll zero times). See corrected test suite for the true benchmark.
(Note: I haven't inspected all test cases, others might be flawed as well)
As you can see, we're talking about 10x faster/slower on a scale of millions of operations per second, which is not significant enough to worry about.
A possible disadvantage of that style is readability to other developers, which is more important than the "performance boost".
Judge yourself, what's more readable?
// Chrome 21: 5M operations per second
var a;
while ((a = arr[i++]) !== undefined) {
someFn(a);
}
// Chrome 21: 324k operations per second
for (var i = 0; i < arr.length; i++) {
someFn(arr[i]);
}
The major disadvantage I can see is that you can't break out of the loop! You'll hit an unresponsive UI in no time with that.
disadvantages:
1. if a[i] has been used it is no longer undefined. Thus you may do more than anticipated.
2. readability, it is difficult to know the end point (unless you put some comments ;)
nothing else.
the new revision still doesn't differ that much, but if it's speed you need then comment well and test well.
If your function "someFn(a);" has a timer of more than in these tests then i'd recommend testing your own loop if it is that important.
If not always stick to tidy coding.

Improving Efficiency in jQuery function

The while statement in this function runs too slow (prevents page load for 4-5 seconds) in IE/firefox, but fast in safari...
It's measuring pixel width of text on a page and truncating until text reaches ideal width:
function constrain(text, ideal_width){
$('.temp_item').html(text);
var item_width = $('span.temp_item').width();
var ideal = parseInt(ideal_width);
var smaller_text = text;
var original = text.length;
while (item_width > ideal) {
smaller_text = smaller_text.substr(0, (smaller_text.length-1));
$('.temp_item').html(smaller_text);
item_width = $('span.temp_item').width();
}
var final_length = smaller_text.length;
if (final_length != original) {
return (smaller_text + '…');
} else {
return text;
}
}
Any way to improve performance? How would I convert this to a bubble-sort function?
Thanks!
move the calls to $() outside of the loop, and store its result in a temporary variable. Running that function is going to be the slowest thing in your code, aside from the call to .html().
They work very very hard on making the selector engines in libraries fast, but it's still dog slow compared to normal javascript operations (like looking up a variable in the local scope) because it has to interact with the dom. Especially if you're using a class selector like that, jquery has to loop through basically every element in the document looking at each class attribute and running a regex on it. Every go round the loop! Get as much of that stuff out of your tight loops as you can. Webkit runs it fast because it has .getElementsByClassName while the other browsers don't. (yet).
Instead of removing one character at time until you find the ideal width, you could use a binary search.
I see that the problem is that you are constantly modifying the DOM in the loop, by setting the html of the temp_item, and then re reading the width.
I don't know the context of your problem, but trying to adjust the layout by measuring the rendered elements is not a good practice from my point of view.
Maybe you could approach the problem from a different angle. Truncating to a fixed width is common.
Other possibility (hack?) if dont have choices, could be to use the overflow css property of the container element and put the … in other element next to the text. Though i recommend you to rethink the need of solving the problem the way you are intending.
Hugo
Other than the suggestion by Breton, another possibility to speed up your algorithm would be to use a binary search on the text length. Currently you are decrementing the length by one character at a time - this is O(N) in the length of the string. Instead, use a search which will be O(log(N)).
Roughly speaking, something like this:
function constrain(text, ideal_width){
...
var temp_item = $('.temp_item');
var span_temp_item = $('span.temp_item');
var text_len_lower = 0;
var text_len_higher = smaller_text.length;
while (true) {
if (item_width > ideal)
{
// make smaller to the mean of "lower" and this
text_len_higher = smaller_text.length;
smaller_text = text.substr(0,
((smaller_text.length + text_len_lower)/2));
}
else
{
if (smaller_text.length>=text_len_higher) break;
// make larger to the mean of "higher" and this
text_len_lower = smaller_text.length;
smaller_text = text.substr(0,
((smaller_text.length + text_len_higher)/2));
}
temp_item.html(smaller_text);
item_width = span_temp_item.width();
}
...
}
One thing to note is that each time you add something to the DOM, or change the html in a node, the page has to redraw itself, which is an expensive operation. Moving any HTML updates outside of a loop might help speed things up quite a bit.
As other have mentioned, you could move the calls to $() to outside the loop. You can create a reference to the element, then just call the methods on it within the loop as 1800 INFORMATION mentioned.
If you use Firefox with the Firebug plugin, there's a great way of profiling the code to see what's taking the longest time. Just click profile under the first tab, do your action, then click profile again. It'll show a table with the time it took for each part of your code. Chances are you'll see a lot of things in the list that are in your js framework library; but you can isolate that as well with a little trial and error.

Categories