网站推广.NET

网站推广.NET

为什么jquery each比js for循环运行速度慢?

来源:互联网

其实查看jquery的源代码,发现each的代码很简单,但为什么性能和原生的for循环相差几十倍呢?

jQuery的each的核心代码


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

看着很简单,但为什么会慢很多呢?

编写测试代码如下:


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))); }

运行测试,发现,第一个和第二个相差不是很大,这说明由于break这个判断导致的性能差异很少,但第二个和第三个,第四个偏差就就不止一倍了,而第二个和第三个唯一的区别就是调用了call,看来call会导致性能损失,因为call会切换上下文,当然jQuery的each慢还有其他原因,它还在循环中调用了其他的方法,call只是一个原因罢了。

因此可以说call,和apply都是js中比较消耗性能的方法,在性能要求严格时,建议少用。

下面在通过一段代码看下jquery的each和js原生for循环性能对比


<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"> <p><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();" /></p> <p> </form> </body> </html>

输入出入:

for循环执行时间:1
each循环执行时间:3

两次结果直接说明了问题。

标签: jquery each