Maison  >  Article  >  interface Web  >  La raison pour laquelle Each de jQuery est beaucoup plus lent que la boucle for native de JS

La raison pour laquelle Each de jQuery est beaucoup plus lent que la boucle for native de JS

高洛峰
高洛峰original
2016-12-29 10:46:511093parcourir

En fait, en regardant le code source de jQuery, j'ai trouvé que le code de chacun est très simple, mais pourquoi les performances sont-elles différentes des dizaines de fois de celles de la boucle for native ?

Le code de base de chacun des jQuery

for (; i < length; i++) { 
value = callback.call(obj[i], i, obj[i]); 
if (value === false) { 
break; 
} 
}

Semble très simple, mais pourquoi est-il tellement plus lent ?

Écrivez le code de test comme suit :

var length=300000; 
function GetArr() { 
var t = []; 
for (var i = 0; i < length; i++) { 
t[i] = i; 
} 
return t; 
} 
function each1(obj, callback) { 
var i = 0; 
var length = obj.length 
for (; i < length; i++) { 
value = callback(i, obj[i]); 
/* if ( value === false ) {去掉了判断 
break; 
}*/
} 
} 
function each2(obj, callback) { 
var i = 0; 
var length = obj.length 
for (; i < length; i++) { 
value = callback(i, obj[i]);/*去掉了call*/
if (value === false) { 
break; 
} 
} 
} 
function each3(obj, callback) { 
var i = 0; 
var length = obj.length 
for (; i < length; i++) { 
value = callback.call(obj[i], i, obj[i]);/*自己写的call*/
if (value === false) { 
break; 
} 
} 
} 
function Test1() { 
var t = GetArr(); 
var date1 = new Date().getTime(); 
var lengtharr = t.length; 
var total = 0; 
each1(t, function (i, n) { 
total += n; 
}); 
var date12 = new Date().getTime(); 
console.log("1Test" + ((date12 - date1))); 
} 
function Test2() { 
var t = GetArr(); 
var date1 = new Date().getTime(); 
var total = 0; 
each2(t, function (i, n) { 
total += n; 
}); 
var date12 = new Date().getTime(); 
console.log("2Test" + ((date12 - date1))); 
} 
function Test3() { 
var t = GetArr(); 
var date1 = new Date().getTime(); 
var total = 0; 
each3(t, function (i, n) { 
total += n; 
}); 
var date12 = new Date().getTime(); 
console.log("3Test" + ((date12 - date1))); 
} 
function Test4() { 
var t = GetArr(); 
var date1 = new Date().getTime(); 
var total = 0; 
$.each(t, function (i, n) { 
total += n; 
}); 
var date12 = new Date().getTime(); 
console.log("4Test" + ((date12 - date1))); 
}

Exécutez le test et constatez que la différence entre le premier et le second n'est pas très grande, ce qui montre qu'il y a peu de différence de performances due au jugement de rupture. Mais les deuxième, troisième et quatrième écarts sont plus du double, et la seule différence entre le deuxième et le troisième est que l'appel est appelé, car l'appel changera de contexte. Bien sûr, il existe d'autres raisons pour lesquelles chacun de jQuery est lent. Il appelle également d'autres méthodes dans la boucle, et l'appel n'est qu'une des raisons.

On peut donc dire que call et apply sont des méthodes relativement gourmandes en performances en js. Lorsque les exigences de performances sont strictes, il est recommandé de les utiliser avec parcimonie.

Regardons la comparaison des performances entre chaque boucle for de jquery et js native à travers un morceau de code

<html xmlns="http://www.w3.org/1999/xhtml"> 
<head runat="server"> 
<title>for与each性能比较</title> 
<script src="../Cks/jquery-1.7.1.min.js" type="text/javascript"></script> 
<script type="text/javascript" language="javascript"> 
function getSelectLength() { 
var time1 = new Date().getTime(); 
var len = $("#select_test").find("option").length; 
var selectObj = $("#select_test"); 
for (var i = 0; i < len; i++) { 
if (selectObj.get(0).options[i].text == "111111") { 
selectObj.get(0).options[i].selected = true; 
break; 
} 
} 
var time2 = new Date().getTime(); 
alert("for循环执行时间:" + (time2 - time1)); 
time1 = new Date().getTime(); 
$("#select_test").find("option").each(function () { 
if ($(this).text() == "111111") { 
$(this)[0].selected = true; 
} 
}); 
time2 = new Date().getTime(); 
alert("each循环执行时间:" + (time2 - time1)); 
} 
</script> 
</head> 
<body> 
<form id="form1" runat="server"> 
<div><select id="select_test"> 
<option value=&#39;1&#39;>111111</option> 
<option value=&#39;2&#39;>222222</option> 
<option value=&#39;3&#39;>333333</option> 
<option value=&#39;4&#39;>444444</option> 
<option value=&#39;5&#39;>5</option> 
<option value=&#39;6&#39;>6</option> 
<option value=&#39;7&#39;>7</option> 
<option value=&#39;8&#39;>8</option> 
<option value=&#39;9&#39;>9</option> 
<option value=&#39;10&#39;>10</option> 
<option value=&#39;11&#39;>11</option> 
<option value=&#39;12&#39;>12</option> 
<option value=&#39;13&#39;>13</option> 
<option value=&#39;14&#39;>14</option> 
<option value=&#39;15&#39;>15</option> 
<option value=&#39;16&#39;>16</option> 
<option value=&#39;17&#39;>17</option> 
<option value=&#39;18&#39;>18</option> 
<option value=&#39;19&#39;>19</option> 
<option value=&#39;20&#39;>20</option> 
</select><input type="button" value="开始比较" onclick="getSelectLength();" /></div> 
<div> 
</form> 
</body> 
</html>

Écart d'entrée :

Temps d'exécution de la boucle For : 1
Durée d'exécution de chaque boucle : 3

Les deux résultats illustrent directement le problème.

Ce qui précède est la raison pour laquelle jQuery Each est beaucoup plus lent que les performances de boucle native JS introduites par l'éditeur. J'espère que cela vous sera utile. Si vous avez des questions, veuillez me laisser un message. et l'éditeur répondra à tout le monde rapidement. Je voudrais également vous remercier tous pour votre soutien au site Web PHP chinois !


Pour plus d'articles sur les raisons pour lesquelles Each de jQuery est beaucoup plus lent que la boucle for native de JS, veuillez faire attention au site Web chinois de PHP !


Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn