views:

98

answers:

3

Previously answered questions here said that this was the fastest way:

//nl is a NodeList
arr=Array.prototype.slice.call(nl);

In benchmarking on my browser I have found that it is more than 3 times slower than this:

arr=[];
for(var i=0,n; n=nl[i]; ++i) arr.push(n);

They both produce the same output, but I find it hard to believe that my second version is the fastest possible way, especially since people have said otherwise here.

Is this a quirk in my browser (Chromium 6)? Or is there a faster way?

EDIT: For anyone who cares, I settled on the following (which seems to be the fastest in every browser that I tested):

//nl is a NodeList
var l=[]; // Will hold the array of Node's
for(var i=0, ll=nl.length; i!=ll; l.push(nl[i++]));
+2  A: 

The second one tends to be faster in some browsers, but the main point is that you have to use it because the first one is just not cross-browser. Even though The Times They Are a-Changin'

@kangax (IE 9 preview)

Array.prototype.slice can now convert certain host objects (e.g. NodeList’s) to arrays — something that majority of modern browsers have been able to do for quite a while.

galambalazs
??? Both are cross-browser compatible -- Javascript (at least if it claims to be compatible with the ECMAscript spec) is Javascript; Array, prototype, slice, and call are all features of the core language + object types.
Jason S
but they cannot be used on NodeLists in IE (I know it sucks, but hey see my update)
galambalazs
because NodeLists are not part of the language, they are part of the DOM API, which is known to be buggy/unpredictable especially in IE
galambalazs
+1  A: 

Check out this blog post here that talks about the same thing. From what I gather, the extra time might have to do with walking up the scope chain.

Vivin Paliath
Interesting. I just did some similar tests now and Firefox 3.6.3 shows no increase in speed doing it either way, while Opera 10.6 has a 20% increase and Chrome 6 has a 230% (!) increase doing it the manual iterate-push way.
jairajs89
@jairajs89 quite strange. It appears that the `Array.prototype.slice` is browser-dependant. I wonder what algorithm each of the browsers are using.
Vivin Paliath
+2  A: 
CMS
I wonder how the reverse for loop holds up against these... `for (var i=o.length; i--;)` ... did the 'for loop' in these tests reevaluate the length property on every iteration?
no