2010-12-15 14 views
9

Aktualizacja Dodano jsfiddle - patrz dno postujQuery różnica wydajności bez „każdego”

Obecnie mam funkcję ponowne włączenie wszystkich pól niepełnosprawnych na ekranie. Mimo, że działa dość szybko (< 1ms zgodnie z Firebug Profiler), jestem w trakcie sprzątania wszystkie JavaScript w moich ekranów i zorientowali ta szczególna funkcja wydawała się być nieco zbędny:

function enableDisabledFields() { 
    $('[disabled]').each(function(i) { 
     $(this).removeAttr('disabled'); 
    }); 
} 

byłem pod wrażenie, że te 3 linie można wymienić w następujący sposób, i spodziewam się, jeśli nie lepiej niż co najmniej równy wydajności.

function enableDisabledFields() { 
    $('[disabled]').removeAttr('disabled'); 
} 

Podobno się mylę. Pierwsza gra o wiele lepiej i nie do końca rozumiem dlaczego. Nawet dodanie dodatkowych selektorów, takich jak: input, nie powoduje różnicy (a nawet ją pogarsza).

Czy ktoś może wyjaśnić moje zamieszanie? Dzięki.

Edycja Powinienem dodać, że używamy starej wersji jQuery - 1.3.1 Wierzę.

Edit2 Oto niektóre linki jsFiddle. Należy pamiętać, że mogę nie rozumieć profilera Firebuga (, które, jak mi się wydaje, wydaje się być zgodne z przypadkiem).

Opcja 1: http://jsfiddle.net/kcut7/

Opcja 2: http://jsfiddle.net/ZgZpU/

+1

Czy masz szansę ustawić parę stron na http://jsfiddle.net/? –

+0

kiedy mówisz "wykonuj o wiele lepiej", jakie są dane liczbowe dla obu? – Ben

+0

oba mają to samo prawo? – kobe

Odpowiedz

4

jQuery 1.3.1 jest to realizowane w nieco inny sposób do aktualnych wersjach

v1.4.4

removeAttr: function(name, fn) { 
    return this.each(function(){ 
     jQuery.attr(this, name, ""); 
     if (this.nodeType === 1) { 
      this.removeAttribute(name); 
     } 
    }); 
}, 

v1.3.1

jQuery.each({ 
    removeAttr: function(name) { 
     jQuery.attr(this, name, ""); 
     if (this.nodeType == 1) 
      this.removeAttribute(name); 
    } 
}, function(name, fn){ 
    jQuery.fn[ name ] = function(){ 
     return this.each(fn, arguments); 
    }; 
}); 

Funkcjonalność jest mniej więcej taka sama, jak używać .each() we wszystkich przypadkach, aby przetworzyć listę. Definicja każdego nie zmienił się zasadniczo w ogóle:

// args is for internal usage only 
each: function(object, callback, args) { 
    var name, i = 0, 
     length = object.length, 
     isObj = length === undefined || jQuery.isFunction(object); 

    if (args) { 
     if (isObj) { 
      for (name in object) { 
       if (callback.apply(object[ name ], args) === false) { 
        break; 
       } 
      } 
     } else { 
      for (; i < length;) { 
       if (callback.apply(object[ i++ ], args) === false) { 
        break; 
       } 
      } 
     } 

    // A special, fast, case for the most common use of each 
    } else { 
     if (isObj) { 
      for (name in object) { 
       if (callback.call(object[ name ], name, object[ name ]) === false) { 
        break; 
       } 
      } 
     } else { 
      for (var value = object[0]; 
       i < length && callback.call(value, i, value) !== false; value = object[++i]) {} 
     } 
    } 

    return object; 
}, 

Więc po prostu pętla przy użyciu .call() dużo.

Myślę, że jedynym wyjaśnieniem jak do zwiększenia prędkości z dodatkową zewnętrznej .each() pętli będzie wielkość struktury danych są znacznie zredukowane do pojedynczego elementu przed przekazywana przez wiele warstw połączeń, co jest prawdopodobnie tworzenie lokalnych kopii danych na każdym poziomie. Przekazanie całej listy do rozpatrzenia powoduje, że może to być o wiele bardziej obciążające, musiałby profilować wykorzystanie sterty, aby powiedzieć.

+1

Alert pro-ness! :RE – Fred

Powiązane problemy