what's more efficient? checking == or just mutating the variable? - javascript

Imagine I had a variable called X.
Let's say every 5 seconds I wanted to make X = true. (it could be either true or false in between these 5 seconds, but gets reset to true when the 5 seconds are up).
Would it be more efficient to check if the value is already true, then if not, reassign it to true? Or just have X = true?
in other words, which would run faster?
if(x==false){
x = true;
}
vs
x = true;
On one hand, the first program won't mutate the variable if it doesn't have to. On the other hand, the second program doesn't need to check what X is equal to; it dives straight in.

It nearly always doesn't matter. Write the code that is easiest to understand and maintain. Only optimize it if necessary.
The best way to be sure is to test it. Profile your code.
Which is faster might depend on the browser.
Which is faster depends on whether the variable is usually true or usually false.
Having said that, I'd guess in most scenarios setting a variable without testing it will be faster.

Really depends on your data :)
If x == false 90% of the time, then a straight assignment to x would be faster.
This is one of those places where you probably don't want to worry about efficiency, and if you really do, profile it ..

Disclaimer/Warning:
This is a micro-optimization, and will never affect the efficiency of your program in a way that is measurable by users. If you turn off all compiler optimizations, and run an excellent profiler, you may be able to quantify the effects - but no user will ever notice.
This is especially true for your situation, where the code in question is only run every few seconds. The time spent profiling would probably be better spent improving other parts of your application.
Also, in these situations readability should always prevail over non-bottleneck micro-optimizations (although my answer below takes only runtime efficiency into account, as requested). Therefore my recommended code for you to use in this situation is x=true, since it's the easiest to read and understand.
Finally, if adding the check will improve speed, the compiler probably already knows that and will do it for you, so you can't go wrong with x=true (that's why you should turn off optimizations before running the profiler).
Answer:
The only true way to figure this out is by profiling. You may find that the 0 test (x==false) basically takes no time at all, and therefore it is worth including due to the time it saves when x turns out to be true. Or you may find that the test takes long enough that it wastes too much time when x turns out to be false.
My guess is that the test is unecessary. That's because 0-testing and other bitwise operations (and, or, etc) are all so fast that I usually treat them as taking the same elementary amount of time. And if 0-testing takes the same amount of time as an OR operation (setting to true), then the 0-test is a redundant waste of time. Profiling could prove me wrong of course, and my guess is based on loose assumptions about bitwise operations, so if you choose to run a profiler and figure this out I'd definitely be interested in the results.

The efficiency your are trying to attain by this is minute compared the efficiency attained by the quality of your overall design.

Related

Would calling Performance API frequently be causing a performance issue?

I want to measure the memory usage of my web SPA using performance.memory, and the purpose is to detect if there is any problem i.e. memory leak during the webapp's lifetime.
For this reason I would need to call this API for specific time interval - it could be every 3 second, every 30 second, or every 1 minute, ... Then I have a question - to detect any issue quickly and effectively I would have to make the interval as short as I could, but then I come up with the concern about performance. The measuring itself could affect the performance of the webapp if the measuring is such a expensive task (hopefully I don't think that is the case though)
With this background above, I have the following questions:
Is performance.memory such a method which would affect browser's main thread's performance so that I should care about the frequency of usage?
Would there be a right way or procedure to determine whether a (Javascript) task is affecting the performance of a device? If question 1 is uncertain, then I would have to try other way to find out the proper interval for calling of memory measurement.
(V8 developer here.)
Calling performance.memory is pretty fast. You can easily verify that in a quick test yourself: just call it a thousand times in a loop and measure how long that takes.
[EDIT: Thanks to #Kaiido for highlighting that this kind of microbenchmark can in general be very misleading; for example the first operation could be much more expensive; or the benchmark scenario could be so different from the real application's scenario that the results don't carry over. Do keep in mind that writing useful microbenchmarks always requires some understanding/inspection of what's happening under the hood!
In this particular case, knowing a bit about how performance.memory works internally, the results of such a simple test are broadly accurate; however, as I explain below, they also don't matter.
--End of edit]
However, that observation is not enough to solve your problem. The reason why performance.memory is fast is also the reason why calling it frequently is pointless: it just returns a cached value, it doesn't actually do any work to measure memory consumption. (If it did, then calling it would be super slow.) Here is a quick test to demonstrate both of these points:
function f() {
if (!performance.memory) {
console.error("unsupported browser");
return;
}
let objects = [];
for (let i = 0; i < 100; i++) {
// We'd expect heap usage to increase by ~1MB per iteration.
objects.push(new Array(256000));
let before = performance.now();
let memory = performance.memory.usedJSHeapSize;
let after = performance.now();
console.log(`Took ${after - before} ms, result: ${memory}`);
}
}
f();
(You can also see that browsers clamp timer granularity for security reasons: it's not a coincidence that the reported time is either 0ms or 0.1ms, never anything in between.)
(Second) however, that's not as much of a problem as it may seem at first, because the premise "to detect any issue quickly and effectively I would have to make the interval as short as I could" is misguided: in garbage-collected languages, it is totally normal that memory usage goes up and down, possibly by hundreds of megabytes. That's because finding objects that can be freed is an expensive exercise, so garbage collectors are carefully tuned for a good compromise: they should free up memory as quickly as possible without wasting CPU cycles on useless busywork. As part of that balance they adapt to the given workload, so there are no general numbers to quote here.
Checking memory consumption of your app in the wild is a fine idea, you're not the first to do it, and performance.memory is the best tool for it (for now). Just keep in mind that what you're looking for is a long-term upwards trend, not short-term fluctuations. So measuring every 10 minutes or so is totally sufficient, and you'll still need lots of data points to see statistically-useful results, because any single measurement could have happened right before or right after a garbage collection cycle.
For example, if you determine that all of your users have higher memory consumption after 10 seconds than after 5 seconds, then that's just working as intended, and there's nothing to be done. Whereas if you notice that after 10 minutes, readings are in the 100-300 MB range, and after 20 minutes in the 200-400 MB range, and after an hour they're 500-1000 MB, then it's time to go looking for that leak.

What should and shouldn't I cache in javascript?

I know that it's a good idea to cache objects that will be used many times. But what about if I will use the following many times:
var chacheWindow = window;
var chacheDocument = document;
var chacheNavigator = navigator;
var chacheScreen = screen;
var chacheWindowLocationHash = window.location.hash;
var chacheDocumentBody = document.body;
Maybe it is only good to chace stuff between <html></html>? Please explain.
The point of caching is to avoid either:
Typing long names repeatedly
Every one of your examples has a longer name then the original so you don't get that benefit
Avoiding making an expensive operation repeatedly (or a slightly costly operation, e.g. array.length before a for loop, a very large number of times)
There is no sign that you are getting that benefit either.
You probably shouldn't be copying the references to local variables at all.
Pretty hard to say exactly what you should cache.
I wouldn't cache native global objects or things that may change. What you are doing in your example is just creating another reference to the same object.
References to DOM elements should be cached, else you will spend time to serach for them again. Also result of functions that make heavy operations could be cached.
You can use some profiler and see the performences on different functions to get a hint on what you should cache.
Caching is a double edged sword. If you've got some value that's intensive to calculate or requires a round trip to the server, caching that is a fantastic idea. For pretty much all of the values that you specified in your question, you're not buying yourself anything. You're simply replacing one variable reference with another.
Generally speaking it's not a good idea to bog yourself down in these micro-optimizations. Optimizing and improving performance is good, but your time is generally better spent looking for that loop that does way too much work or a fixing bad algorithm than handling this type of case where if there's any improvement at all, you're only looking at an improvement of nanoseconds at best - but again for the values you mentioned you will see absolutely no improvement.

Boolean vs Int in Javascript

I always assumed that booleans were more efficient than ints at storing an on/off value - considering that's their reason for existence. I recently decided to check if this is true with the help of jsperf, and it came up with some contrary results!
http://jsperf.com/bool-vs-int
Here is the first test I tried. Toggling the value of the on/off switch. On Chrome it's significantly faster to do this using 1/0, but on firefox it's slightly faster to do this using bool. Interesting.
http://jsperf.com/bool-vs-int-2
And here's the second test I tried. Using them in a conditional. This appears to have significant advantage for ints as opposed to bools, up to 70% faster to use 1/0 instead of booleans - on both firefox and chrome. Wtf?
I guess my question is, am I doing something wrong? Why are ints so much better at boolean's job? Is the only value of using bools clarity, or am I missing something important?
Disclaimer, I can only speak for Firefox, but I guess Chrome is similar.
First example (http://jsperf.com/bool-vs-int):
The Not operation
JägerMonkey (Spidmonkey's JavaScript methodjit) inlines the check for boolean first and then just xors, which is really fast (We don't know the type of a/b, so we need to check the type).
The second check is for int, so if a/b would be a int this would be a little bit slower.
Code
The Subtract operation.
We again don't know the type of c/d. And again you are lucky we are going to assume ints and inline that first. But because in JavaScript number operations are specified to be IEEE 754 doubles, we need to check for overflow. So the only difference is "sub" and a "conditional jump" on overflow vs. plain xor in case 1.
Code
Second example:
(I am not 100% sure about these, because I never really looked at this code before)
and 3. The If.
We inline a check for boolean, all other cases end up calling a function converting the value to a boolean.
Code
The Compare and If.
This one is a really complex case from the implementation point of view, because it was really important to optimize equality operations. So I think I found the right code, that seems to suggest we first check for double and then for integers.
And because we know that the result of a compare is always a boolean, we can optimize the if statement.
Code
Followup I dumped the generated machine code, so if you are still interested, here you go.
Overall this is just a piece in a bigger picture. If we knew what kind of type the variables had and knew that the subtraction won't overflow then we could make all these cases about equally fast.
These efforts are being made with IonMonkey or v8's Crankshaft. This means you should avoid optimizing based of this information, because:
it's already pretty fast
the engine developers take care of optimizing it for you
it will be even faster in the future.
your test was a bit off due to the definition of "function" and "var" and the call for the function. The cost to define function and variables and calling them will differ from engine to engine. I modified your tests, try to re-run with your browsers (note that IE was off because the first run was weird but consecutive runs were as expected where bool is fastest): http://jsperf.com/bool-vs-int-2/4
I don't know but in the second test it does
if(a) bluh();
vs
if(c == 1) bluh();
maybe c==1 is faster because you're comparing a value with one with the same type
but if you do if(a) then js need to check if the value evaluates to true, not just if it is true...
That could be the reason...
Maybe we need to test
if(c==1)
vs
if(a===true) with three =
For me the choice would be based on API usage. Always return that which is most useful. If I use secondary code, I'd favor methods that return booleans. This probably makes the code ready to be chained. The alternative is to provide overloaded methods.
Diggin' deep here. Regarding performance, I'm still unsure (this is why I found this thread) if booleans vs 0/1 is faster when computing and it still seems heavily browser-dependent. But take into account, that in extremely huge datasets the data has to be downloaded by the user first anyway:
"true" and "false" obv take up 4 or 5 characters respectively, whereas 0 and 1 are only 1 character. So it might save you a little bit of bandwidth at least, so less time to load and only after that is it up to the client's browser and hardware how to deal with those types, which seems pretty much negligible.
As a little bonus and to actually contribute something, since (I think?) no one mentioned it here, if you are going with the 0 and 1 approach, instead of using if-statements you can use bitwise operations to toggle between them, which should be pretty fast:
x=0;
x^=1; // 1
x^=1; // 0
This is the equivalence to using this toggle for booleans:
x=false;
x=!x; // true
x=!x; // false

'Fixed' for loop - what is more efficient?

I'm creating a tic-tac-toe game, and one of the functions has to iterate through each of the 9 fields (tic-tac-toe is played on a 3x3 grid). I was wondering what is more efficient (which one is perhaps faster, or what is the preferred way of scripting in such situation) - using two for nested loops like this:
for(var i=0; i<3; i++) {
for(var j=0; j<3; j++) {
checkField(i, j);
}
}
or hard-coding it like this:
checkField(0, 0);
checkField(0, 1);
checkField(0, 2);
checkField(1, 0);
checkField(1, 1);
checkField(1, 2);
checkField(2, 0);
checkField(2, 1);
checkField(2, 2);
As there are only 9 combinations, it would be perhaps overkill to use two nested for loops, but then again this is clearer to read. The for loop, however, will increment variables and check whether i and j are smaller than 3 every time as well.
In this example, the time saving at least might be negligible, but what is the preferred way of coding in this case?
Thanks.
Do not hard code 9 lines of the same code!
Readability
Flexibility / Maintenance
Code Length
This is a premature micro-optimization. In this case always go for the clearer solution - so use the for loops:) And by the way, think about if tomorrow the grid is 4x4:)
Time savings: negligible. Probably un-measurable.
Preferred style: nested for loops. Ok, you'll probably never make it a 4x4 or 5x5 or 3d (or 4d!) tic-tac-toe - but it's a good habit to get into. Also easier to see if you forgot something and avoids cut-and-paste errors.
Ironically hard-coding the checks will probably be faster, but (and here's the important bit) meaninglessly so.
As such, what you should really aim for is the maximum clarity of intent for what you're trying to achieve. Also, you should try and make life easier for any future improvements (that may not be carried out by you.) For example, if the tic-tac-toe grid was expanded to 4x4 which solution would be the best?
On this basis I'd be tempted to go with the loop approach along with the appropriate level of commenting, etc.
We should forget about small
efficiencies, say about 97% of the
time: premature optimization is the
root of all evil.
-- Donald Knuth
Definitely the first one. First of all, the performance difference will be absolutely negligible - my guess is the unrolled program will run slower because more time is required to compile/interpret it because it is longer (plus, additional client, server and router processing power and bandwidth will be required).
Secondly, and as a generalization, you don't know which version would be faster. Maybe some interpreter would increment registers for the first version, but load the parameters from memory (waaay slower) for the second one?
Especially in the case of JavaScript, you have absolutely no fixed specification on how fast (future!) interpreters and compilers work, so this "optimization" is absolutely pointless and confusing other programmers working with your code at best.
Please don't hardcode it. Never do something like that.
More than one time? Use a loop.
Also, you are worrying about a problem you don't have, really.
As you mentioned, the time saving will be negligible. Even if you would put that grid to a 100 times 100 square, you still won't see any difference.
If we go a bit larger though, say 10.000 times 10.000, we might see some difference. I wonder what that might be, because the compilers and optimisers are very good and especially in a loop the environment might speed things up by having this information (function will be called several times).
Why don't you try it out and share your results with us?
In practise, however, I would never recommend going for the second approach. Readability and flexibility is far more important than CPU time. And optimising early, as they say, is quite evil in itself because it obfuscates the code and introduces a lot of unnecessary complexity without really contributing to performance.

Javascript: Optimizing details for Critical/Highly Processed Javascript code

I've been looking through a lot of Javascript Optimizing and most of them talk about string concatenation and a few other big ones found here, but I figured there had to be more details that you can optimize for when speed is critical and the processing of those pieces of code is very high.
Say you run this code for some reason: (unlikely, I know, but bear with me)
for( var i = 0; i < 100000000000; i++ ) {
//Do stuff
}
And there's no way of getting around having a loop that big... You're going to want to make sure that all the stuff you're doing in that loop is optimized to the point that you can't optimize it anymore... or your website will hang.
Edit: I'm not necessarily talking about a loop, what about a function that's repeatedly called such as onmousemove? Although in most cases we shouldn't need to use onmousemove, there are some cases that do. This questions is for those cases.
Using JQuery as our JS library
So what I would like is tips for optimizing, but only the more uncommon ones
- ie. Speed differences between switch or if-else
If you'd like to see the more common ones, you can find them here:
Optimizing Javascript for Execution Speed
Javascript Tips and Tricks; Javascript Best Practices
Optimize javascript pre-load of images
How do you optimize your Javascript
Object Oriented Javascript best practices
"And there's no way of getting around having a loop that big... "
In the real world of RIA, you HAVE to get around the big loops. As important as optimization is learning how to break large loops into small loops, and giving time to the browser to deal with its UI. Otherwise you'll give your users a bad experience and they won't come back.
So I'd argue that BEFORE you learn funky JS optimizations, you should know how to break a large loop into chunks called by setTimeout() and display a progress bar (or let animated GIFs loop).
Perceived speed is often more important than actual speed. The world of the client is different from the world of the server.
When animating, learn how to find out if you're running on a lame browser (usually IE) and try for a worse framerate (or just don't animate). I can get some animations to go 90fps in a good browser but just 15fps in IE. You can test for the browser, but it's usually better to use timeouts and the clock to see how animations are performing.
Also, for genuine speedups, learn how to use web workers in Gears and in newer browsers.
You can speed up this mofo thus:
for (var i = 100000000; i--;) {
//Do stuff
}
Reverses the loop and checks only for
i--
instead of
i < 10000000 and i < 10000000 = true
Performance gain of 50% in most browsers
Saw this in a great Google Code talk # http://www.youtube.com/watch?v=mHtdZgou0qU
The talk contains some other great tricks.
Good luck!
If it doesn't need to be synchronous, convert the loops into a recursive implementation with setTimeout calls
for( var i = 0; i < 100000000000; i++ ) {
//Do stuff
}
Can probably written as
function doSomething(n)
{
if (n === 0) return some_value;
setTimeout(function(){doSomething(n-1);}, 0);
}
OK, this might not be a good example, but you get the idea. This way, you convert long synchronous operations into an asynchronous operation that doesn't hang the browser. Very useful in certain scenarios where something doesn't need to be done right away.
Using split & join instead of replace:
//str.replace("needle", "hay");
str.split("needle").join("hay");
Store long reference chains in local variables:
function doit() {
//foo.bar.moo.goo();
//alert(foo.bar.moo.x);
var moo = foo.bar.moo;
moo.goo();
alert(moo.x);
}
After seeing a few good answers by the people here, I did some more searching and found a few to add:
These are tips on Javascript optimizing when you're looking to get down to the very little details, things that in most cases wouldn't matter, but some it will make all the difference:
Switch vs. Else If
A commonly used tactic to wring
whatever overhead might be left out of
a large group of simple conditional
statements is replacing If-Then-Else's
with Switch statements.
Just incase you wanted to see benchmarking you can find it here.
Loop Unrolling
To unroll a loop, you have it do more
than one of the same step per
iteration and increment the counter
variable accordingly. This helps a lot
because you then decrease the number
of times you are checking the
condition for the loop overall. You
must be careful when doing this though
because you may end up overshooting
bounds.
See details and benchmarking here.
Reverse Loop Counting
Reverse your loop so that it counts
down instead of up. I have also seen
in various documents about
optimization that comparing a number
to zero is much quicker than comparing
it to another number, so if you
decrement and compare to zero it
should be faster.
See more details and benchmarking here.
Duff's Device
It's simple, but complicated to grasp at first. Read more about it here.
Make sure to check out the improved version further down that page.
The majority of this information was quoted directly from here: JavaScript Optimization. It's interesting, since it's such an old site it looks at optimization from the perspective of the browser processing power they had back then. Although the benchmarks they have recorded there are for IE 5.5 and Netscape 4.73, their benchmarking tools give accurate results for the browser you're using.
For the people who think these details don't matter, I think it says a bit about the way people perceive the power in advancing technologies we have. Just because our browsers are processing many times faster than what they use to doesn't necessarily mean that we should abuse that processing power.
I'm not suggesting spend hours optimizing two lines of code for 0.005ms, but if you keep some these techniques in mind and implement them where appropriate it will contribute to a faster web. After all, there are still many people using IE 6, so it would be wrong to assume everyone's browsers can handle the same processing.
Which JavaScript engine are we supposed to be targeting? If you're talking about such extreme optimisation, it makes a big difference. For starters, I'll point out that the array.join() trick for string concatenation is only really applicable to Microsoft's JScript engine; it can actually give worse performance on other JS engines.

Categories

Resources