views:

82

answers:

5

The following function simply returns an of elements with the specified tagname in the document. For some reason on successive calls to the function the execution of it gets slower and slower.. I have tested it thoroughly and the for-loop line in the cause, but I don't understand why that would cause a slow down on successive calls.

function getElementsByTagName2(tagName){
    var arr=new Array();
    var elems=document.getElementsByTagName(tagName);
    for(var i=0, len=elems.length; i!=len; arr.push(elems[i++]));
    return arr
}

EDIT: Changed variable names to please user257493.

EDIT1: Just tested jQuery and it has the same issue. The degradation is minor though.

A: 

Make use of the time functions and print output to console so you can actually see where the lag is. You've only shown us one function, not all of the source code. Your problem could be anywhere such as the function it is calling, or simply the way you've set up that for-loop and how it reacts with the document you're working with.

Also, http://www.objectmentor.com/resources/articles/Naming.pdf.

I've been profiling for 30min and it all comes down to 'arr.push(elems[i++])' in the for-loop.
jairajs89
A: 

What goes on between the runs of your function? How does the DOM change? What's the likelihood that each takes successively longer because you've got an increased number of return elements? Also, push is slow. This also works and might speed you up a bit - I show no delays in repeated executions.

function getElementsByTagName2(tagName) { 
  var arr = new Array(), 
  elems = document.getElementsByTagName(tagName); 
  for (var i = 0, len = elems.length; i != len; arr[i] = elems[i], ++i); 
  return arr; 
}
g.d.d.c
A: 

Try to assign the array elements directly, without push.

function getElementsByTagName2(tag, pa){
    pa= pa || document;
    tag= pa.getElementsByTagName(tag);
    var L= tag.length, A= [];
    while(L){
        A[--L]= tag[L];
    }
    return A
}
getElementsByTagName2('*',document.body)
kennebec
Thank, that gave a bit of a speed boost.
jairajs89
+1  A: 

I've tested Your code and it seems to run just fine.

My results (iteration -> time taken (found divs):

1. Firefox:
0 -> 1524 (found 102)
1 -> 1534 (found 102)
2 -> 1518 (found 102)
3 -> 1528 (found 102)
4 -> 1535 (found 102)
...
15 -> 1513 (found 102)
16 -> 1512 (found 102)
17 -> 1513 (found 102)
18 -> 1513 (found 102)
19 -> 1518 (found 102)

2. Chrome:
0 -> 387 (found 102)
1 -> 283 (found 102)
2 -> 268 (found 102)
3 -> 272 (found 102)
4 -> 271 (found 102)
...
15 -> 270 (found 102)
16 -> 279 (found 102)
17 -> 267 (found 102)
18 -> 287 (found 102)
19 -> 272 (found 102)

ghaxx
hmmm.. something must be up on my computer or browser then!
jairajs89
A: 

Does the Prototype to-array method have the same problem?

function $A(iterable) {
  if (!iterable) return [];
  if ('toArray' in Object(iterable)) return iterable.toArray();
  var length = iterable.length || 0, results = new Array(length);
  while (length--) results[length] = iterable[length];
  return results;
}
Douglas