Optimizations
When optimizing, you have to make sure it actually helps. In this case, not really. You’re lucky to see a one millisecond difference on a thousand function calls (in Firefox 1.5 on Mac, at least).
Update (a few minutes after the fact): I realized that Deans function checks for the existence of a property on a node. This lookup could cost more time, so I updated the test case to make sure the if/else clause looked up two properties on the document node. Differences now are 10 - 20 ms (still not very much as we are talking about a thousand invocations).
Update (December 13th, 11 pm): Updated test with Sjoerds suggestions. More interesting results in the comments.




Mark, I think you are slightly missing the point. I was trying to illustrate a general programming technique. That being, perform certain tests once and only once. Object detection performed within loops will probably make your application less responsive. On simple web pages/tests this is negligible but for more complex UIs this is still a factor.
The real point is that good programming practice is good practice.
Dean Edwards | 13 December 2005, 03:59 | link
True. I wonder how well this point will be understood, as you gave a clear example with the
addEvent()code. Also, it’s a good programming practice to test before you optimize :)Mark Wubben | 13 December 2005, 09:55 | link
Running this a 1000 times is not enough. JS rounds time to the nearest 15ms, so the time a test takes has to be a lot longer than that.
I did the test 50000 times. Then A takes 0.7 seconds, B takes 2 seconds and C takes 3 seconds. Which shows that this test is bogus, because C should be the fastest. The problem is that you use string concatenation, which becomes slower the longer the string. And you don’t make the string empty before each test.
As string concatenation is taking too much time for this test, I tried just adding 1 to a number each time. Running the test again (now 500000 times) gives: A 1.1 seconds, B 2.1 seconds and C 0.8 seconds. So C is faster, but even in complex UI (like Xopus) this is not going to help anything.
(Tested in Firefox. IE is slower but the difference between A and C is smaller. So function calls in IE are slower than in Firefox, but if is faster.)
Sjoerd Visscher | 13 December 2005, 11:14 | link
Sjoerd, may I rephrase that as “don’t write test cases at 1 pm because you have an idea for a post”?
I’ll update the test case later, or perhaps I can get yours?
Mark Wubben | 13 December 2005, 16:57 | link
The most valid point about optimizing still being that you need benchmark tests and well defined targets as to what the speed you are aiming for is.
It’s faster! Who cares?
A relevant target would be to consistently parse and display a standard XML in under 0.1s.
Most throwaway stuff I make will not be needing this, but the maturing flock of libraries out there are probably going to incorporate this stuff in the near future (at least I hope are).
Alper | 13 December 2005, 19:06 | link
Here are results for the new test on the Mac:
So we’re talking about a ~ 20ms difference in Firefox and Safari, and a ~70ms difference in Opera, when tested five thousand times.
Mark Wubben | 13 December 2005, 23:20 | link
Mark, the links to comment anchors scroll down to below the actual comment. Couldn’t you fix that?
“JS rounds time to the nearest 15ms, so the time a test takes has to be a lot longer than that.”
That’s not true, is it?
Branstrom | 14 December 2005, 16:33 | link
What about http://dean.edwards.name/weblog/2005/12/js-tip1/#comment2813?
Branstrom | 14 December 2005, 16:35 | link
Branstrom, yeah, I noticed. I’m a bit busy right now, but it will be fixed.
As for the idea posted on Deans site, I’d prefer that solution over the solution Dean originally posted (because of code clarity), but it also contains a risk: another script could be looking for
document.addEventListener ()and be basing behaviour on that. Also, you’d want it for every element in the document, which is not possible in IE.Mark Wubben | 14 December 2005, 19:00 | link
Good point: Test!
I’ve actually used dynamic method assignment. I used it in GlideMenus so that I could have use posLeft and posTop for IE. Those two properties are notably faster, and since IE is slow with animation, I used those properties instead.
moveTo : (ua.ie ? // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndude/html/dude1201.asp function(x,y) {this.x=this.css.posLeft=x;this.y=this.css.posTop=y;} : function(x, y) { this.css.left = (this.x = x) + ua.px; this.css.top = (this.y = y) + ua.px; }),
Garrett Smith | 7 January 2006, 02:44 | link