As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I have a loop that looks like this:
$('#SomeSelectorID').find('.SomeElementsByClassName').each(function () {
$(this).some code here;
$(this).some other code there;
$(this).some other code here and there;
});
If I write at the top of the loop var TheThis = $(this); and then replace $(this) with TheThis is that a performance optimization or not really?
It's a definite performance optimisation. One you'll probably not notice, but that's no reason not to do it.
The code in your example means that the DOM will be interrogated 3 times to look for the $(this) element and then perform the actions on it. Caching it in a variable means that that will only occur once.
If you really want to see the difference try comparing your original with the below in a JSPerf test.
$('#SomeSelectorID').find('.SomeElementsByClassName').each(function () {
var $this = $(this);
$this.some code here;
$this.some other code there;
$this.some other code here and there;
});
Yes there is a performance penalty. I've created a small demo that illustrates using $(this) is slower than using a stored version of it.
JSFiddle demo here.
No I don't think you need to change your code. The benefit in this case will be so small that you will hardly notice any difference. Maybe in another situation where you are developing a game or data processing app it can matter.
Here are the results of my test...
Testing jquery version...
1000000 iterations $(this): 0.006849ms
Testing non-jquery version...
1000000 iterations of this$: 0.001356ms
Of course it is a performance optimization. Whether it is worth it or not, that's the real question. If you are reiterating over the DOM then it would definitely be worth it. In this case, you are just wrapping an object in jQuery so the footprint is much smaller.
That being said, you gain a little bit of performance but lose nothing in terms of readability, maintainability, or other things that you usually have to sacrifice to gain performance, so you may as well make the tweak.
Testing this shows no performance impact, at least on Chrome:
var start = new Date().getTime(),
iterations = 50000;
$('#foo').find('.bar').each(function () {
var that = $(this);
for(var i = 0; i < iterations; i++)
that.find('i');
});
console.log(new Date().getTime() - start);
Using $(this) results are more or less the same.
http://jsfiddle.net/BuREW/
Well, duh.
In general, calling any function is an expense. Calling $() is a HUGE one (compare calling times compared to Vanilla JS) and one that should be avoided as much as possible.
Storing its return value in a variable is always a good thing, but it also avoids certain "gotchas".
For instance, let's say you want to change all .test elements to green and remove the class. You might do this:
$(".test").removeClass("test");
$(".test").css({"color":"green"});
Only to find that it doesn't change the colour to green because $(".test") isn't the same thing anymore.
Conversely, if you had done:
var test = $(".test");
test.removeClass("test");
test.css({"color":"green"});
It works. Of course, this is a trivial example since you can just rearrange the code lines and it works too, but I'm triyng to make a point here :p
Related
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.
Let's say I have a javascript object.
var hash = { a : [ ] };
Now I want to edit the array hash.a 2 ways: first by accessing hash.a every time, second by making a pointer var arr = hash.a to store hash.a's memory address. Is second way faster, or they are the same.
Example:
// first way
hash.a.push(1);
hash.a.push(2);
hash.a.push(3);
hash.a.push(4);
hash.a.push(5);
//second way
var arr = hash.a;
arr.push(1);
arr.push(2);
arr.push(3);
arr.push(4);
arr.push(5);
Thanks a lot!
I don't think there would be any real performance gain, and if there is a slight gain it isn't worth it as you are hampering legibility and maintainability of code + use more memory (creation and garbage collection of another variable arr, also more chances for memory leaks too if you don't handle it properly). I wouldn't recommend it.
In a typical software project, only 20% of the time is development, rest 80% is testing and maintaining it.
You're doing the compiler's job in this situation - any modern compiler will optimize this code when interpreting it so both cases should be the same in terms of performance.
Even if these two cases weren't optimized by the compiler, the performance gains would be negligible. Focus on making your code as readable as possible, and let compiler handle these referencing optimizations.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 8 years ago.
Improve this question
I would like to avoid unresponsive javascript in all browsers.
Is it possible to write code with that in mind?
DETAILS: Problem is that currently there is a potential script block that executes fine in Chrome on my PC, but causing problems on IE (various versions). The worst thing is that I really don't know for sure if it is that script block at all. I will rewrite and solve that. However, I would like to know what exactly I should be avoiding while coding. This...
http://www.sitepoint.com/javascript-execution-browser-limits/
...is an interesting read but it's too general.
EDIT: I'm using jQuery/jQueryUI as well.
EDIT 2: There are patterns/principles to use to avoid particular problems. E.g. singleton pattern, PRG pattern, DRY principle... and such. Is there something like that for this kind of problem?
I've run into problems like this before as well.
The thing to keep in mind as you code, is where does my code begin execution, and where does my code end execution. For all of the time between those two points, the browser's UI thread is blocked, and the browser makers have understandably developed counter measures.
As far as what to avoid, avoid long, continuous loops.
Here's an extreme example:
function howManyMultiplesOfFourBelow(foo) {
var i = 0, j = 0;
while (i < foo) {
i++;
if (i % 4 === 0) {
j++;
}
}
return j;
}
If you pass 10,000,000 to that function, IE will definitely throw a fit. There is more than one way to program around this kind of situation; what I prefer is to break up the code using setTimeout/setInterval. After setting an interval and returning out of a function, we release the UI thread back to the browser, and the browser is in charge of executing the interval as often as we've requested (or as often as it is able).
I combine this with Futures/Promises; In particular, jQuery's implementation.
Using this style, the above example could be rewritten not to block the UI thread during the calculation by leveraging promises, and setInterval.
function howManyMultiplesOfFourBelow(foo) {
var deferred = $.Deferred(),
interval,
i = 0,
j = 0;
interval = setInterval(function () {
if (i >= foo) {
clearInterval(interval);
deferred.resolve(j);
return;
}
i++;
if (i % 4 === 0) {
j++;
}
}, 1);
return deferred.promise();
}
The first important difference is that this function no longer returns the answer, but instead a promise of an answer. So, consuming code might look like this:
howManyMultiplesOfFourBelow(10000000).done(function (multiples) {
//Update the DOM with the answer (multiples)
});
Returning to your question more generally, think about how much of your code must be run continuously, and if any of it could be delayed, or broken up in order to release the UI thread briefly.
Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 11 years ago.
Improve this question
I have a massive collection of methods that I want to shape into a library. How do I begin the process?
Here is the begnning of the consolidation effort: I'm trying to decide if I should do this for my whole code base — move similar items into JavaScript objects.
Below is the consolidation effort followed by the whole code base:
Should I shape my code this way?
Consolidation Effort:
var menu = {
menu_timer:0,
menu_element:0,
/* called when mousing over the top menu item */
top_mouse_over: function (id)
{
menu.bottom_mouse_over();
menu.menu_element=document.getElementById(id);
menu.menu_element.style.visibility='visible';
},
/* hide the menu when the timer runs out */
hide_menu: function()
{
if(menu.menu_element)menu.menu_element.style.visibility='hidden';
},
/* keeps the menu open by clearing the timer when mousing over the menu items */
bottom_mouse_over: function()
{
if(menu.menu_timer)
{
window.clearTimeout(menu.menu_timer);}
},
/* set the timer to hide the menu, required by clearTimeout */
mouse_out: function()
{
menu.menu_timer=window.setTimeout(menu.hide_menu, 1000);
}
};
Entire Code Base:
Moved to codereview
First, refactor.
There no reason for a function called 16 or m6.
A few suggestions:
Use jQuery, Dojo, Zepto or any other library for your AJAX calls and mouse/keyboard events. There's no reason to reinvent the wheel. You now need to test your AJAX functions on every browser in the world. jQuery's AJAX function has already been tested.
try to use prettyDate instead of view_date.
Why do you minimize function names? What's the reason? Compressors can do this for you. Seriously, how can you work with this:
function m2(a,b) {
return document.getElementById(a).innerHTML=b;
}
Look into template functions (such as _.template, jQuery.template, mustache, etc). Look into validation plugins that might make your work easier.
You have 800 lines of code. You can make this to 200 readable lines of code.
Regarding making it a library: depending on the context I usually make it a jQuery plugin or using _.extend. Namespacing it to var menu = {} is sufficient though I'd pick a more relevant name than menu.
Your new approach is certainly an improvement. You should feel free to have your own style, but I would consider taking a conventional approach around documentation generation. In addition, if you take advantage of a library such as jQuery or Prototype, you'll be able to adapt from their style, instead of inventing your own. (I promise it won't stifle your creativity.)
Finally, you may consider pseudo-namespacing your object with a name that's less likely to be overridden in global. "window.menu" strikes me as slightly dangerous. Brand your core object while you namespace it.
Read up on Paul Irish's (Google Chrome, jQuery) method of kick-starting page-specific code.
http://paulirish.com/2009/markup-based-unobtrusive-comprehensive-dom-ready-execution/
I am finally getting around to really implementing some jQuery solutions for my apps (which is seeming to also involve a crash course in javascript).
In studying examples of plugins, I ran across this code. I'm assuming the author created the zero length timer to create some seperation of the running code, so that the init functon would finish quickly.
function hovertipInit() {
var hovertipConfig = {'attribute':'hovertip',
'showDelay': 300,
'hideDelay': 700};
var hovertipSelect = 'div.hovertip';
window.setTimeout(function() {
$(hovertipSelect).hovertipActivate(hovertipConfig,
targetSelectById,
hovertipPrepare,
hovertipTargetPrepare);
}, 0);
}
Is needing this type of seperation common?
Is creating the zero length timer still the best way to handle this situation, or is there a better to to handle this in jQuery?
Thanks,
Jim
Check out this article that explains when this is necessary.
Also check out this related question.
It is not very common, but is necessary when you need to escape the call stack of an event.