引:每个接触JS的开发人员都不可避免的与for循环打交道,毕竟这是遍历必不可少的工具之一。然而当循环次数比较大时,效率问题必须重视。在群众,站长提出了这个话题,回去好好想了下,整理出来,大家一起讨论讨论。
1.倒序比正序效率高?
听好多人说,倒序效率更高,好吧,做个实验,让事实说话
测试代码:
- <html>
- <head>
- <title>New Document </title>
- <scripttype="text/javascript">
- <!--
- function test3(){
- var date1 = new Date();
- var m;
- for(vari=0;i<10000000;i++){
- m = i;
- }
- var date2 = new Date();
- for(vari=9999999;i>=0;i--){
- m = i;
- }
- var date3 = new Date();
- r31.value = (date2-date1);
- r32.value = (date3-date2);
- }
- //-->
- </script>
- </head>
-
- <body>
- <input type ="button" value="测试3" onclick = "test3()"/>
- <input type ="text" id = "r31">
- <input type ="text" id = "r32">
- </body>
- </html>
复制代码
测试结果如下图test1:
第一列值为执行正序时间,第二列为倒序执行时间。
可以看出在IE6和IE7中效率基本持平,而在IE8,谷歌浏览器中,倒序反而比正序还要慢,当然这是在js中做的测试
结论:JS的for循环,在IE6,IE7中倒序的效率不比正序高,反而在IE8与谷歌浏览器中正序效率更高。其他浏览器为测试。
2.循环体中,局部变量优化问题
在循环体内部,我们可能会声明一些局部变量(对象)来处理数据。如果变量声明不当,也会影响效率。
看例子
- <html>
- <head>
- <title>New Document </title>
- <scripttype="text/javascript">
- <!--
- function test2(){
- var date1 = newDate();
- for(var i=0;i<1000000;i++){
- var s = new Array();
- s[0] =1;
- }
- var date2 = newDate();
- for(var i =0,s = newArray();i<1000000;i++){
- s[0] =1;
- }
- var date3 = newDate();
- r21.value =(date2-date1);
- r22.value =(date3-date2);
- }
- //-->
- </script>
- </head>
-
- <body>
- <input type = "button" value="测试2" onclick ="test2()"/>
- <input type = "text" id ="r21">
- <input type = "text" id ="r22">
- </body>
- </html>
复制代码
在循环体中,声明了一个数组作为局部变量。
测试结果如下:
第一列值为在循环体内执行的时间,第二列在起始语句中执行的时间。
可以看出在IE6和IE7中优化的效率接近15倍,在IE8中10倍,谷歌浏览器执行速度快,但也优化了3倍以上,还是在js中做的测试
结论:JS的for循环,在IE6、IE7、E8与谷歌浏览器中通过对局部变量的优化可以成倍的提高执行效率。其他浏览器为测试。
补充:原来都是将局部变量的声明放到for循环外,但站长提醒,这样的话,局部变量的生存周期会变长,直到for的父级执行完后,所占内存才会释放。不过通过做了几个小例子,没有明显的区别,主要是因为在测试中局部变量占用的内存较少,而且这种局部变量的量也较少,所以效果不明显。
3.条件判断语句中,尽量使用变量来判断而不要去调用方法
在for的判断语句中,经常遇到循环变量与某个值进行比较。而这个值经常是list的长度,或者某个数据的大小。虽然这些数据结构有已经定义好的求长求大小的方法。但是每次判断时都会执行一次,也会影响效率。
看列子
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
- <html>
- <head>
- <title>New Document </title>
- <scripttype="text/javascript">
- <!--
- functiontest1(){
- var date1 =new Date();
- var array =new Array(1000000);
- for(var i=0;i<array.length;i++){
- array[i]=0;
- }
- var date2 =new Date();
- for(var i=0,j=array.length;i<j;i++){
- array[i]=1;
- }
- var date3 =new Date();
- r11.value =(date2-date1);
- r12.value =(date3-date2);
- }
- //-->
- </script>
- </head>
-
- <body>
- <input type = "button" value="测试1" onclick ="test1()"/>
- <input type = "text" id ="r11">
- <input type = "text" id ="r12">
- </body>
- </html>
复制代码
执行结果比较
第一列值为在判断语句中有方法调用执行的时间,第二列在判断语句中使用变量执行的时间。
可以看出在IE6、IE7和IE8中接近4倍,谷歌浏览器执行速度快,但也优化了10倍以上
结论:JS的for循环,在IE6、IE7、E8与谷歌浏览器中通过对判断语句的优化可以成倍的提高执行效率。其他浏览器未测试。
4.嵌套循环问题
即一个for循环中还嵌套这另一层for循环,可能这种嵌套是多层的。
这个留给大家自己测试,我的测试结果是里外循环次数相差不大。但是有个原则,尽量把循环次数少的写到最外层。
总结:JS的for循环中,性能的优化主要通过减少循环体中变量的声明和外部方法的调用来实现。例子3中所讲的判断语句的优化其实也是对循环体中外部方法调用的优化。我在写后台时,遇到过在for循环中写SQL的例子,每次循环都访问一次数据库,这个效率是极低的
当然,可能还有其他的需要优化的地方,我暂时先写这些,不对的地方请大家指正。