2025年3月23日 星期日 甲辰(龙)年 月廿二 夜 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > JavaScript

JS优化循环结构(经典)

时间:03-01来源:作者:点击数:135

循环时最耗费资源的操作,任意一点小小的损耗都会被成倍放大,从而影响到程序整体运行的效率。一下两个因素会影响到循环的性能。

  • 每次迭代做什么
  • 迭代的次数

通过减少这两者中一个或全部的执行时间,可以提高循环的整体性能。如果一次循环需要较长时间,那么多次循环将需要更长时间。

示例1

下面使用 3 类循环语句设计一个典型的数组遍历操作。

  • //方法1
  • for (var i = 0;i < items.length;i ++) {
  • process(items[i]);
  • }
  • //方法2
  • var j = 0;
  • while (j < items.length) {
  • process(items[j++]);
  • }
  • //方法3
  • var k = 0;
  • do {
  • process(items[k++]);
  • } while (k < items.length);

减少循环

对于任何循环来说,每次执行循环体都要发生一下操作。

  • 在控制条件中读一次属性(items.length)。
  • 在控制条件中执行一次比较(i < itesm.length)。
  • 判断 i<items.length 表达式的值是不是 true(i < items.length == true)。
  • 一次自加操作(i++)。
  • 一次数组查找(items[i])。
  • 一次函数调用(process(items[i]))。

在循环体内,代码运行速度很大程度上由 process() 对每个项目的操作决定,即便如此,减少每次迭代中操作的总数也可以大幅度提高循环的性能。

优化循环的第一步是减少对象成员和数组项查找的次数。在大多数浏览器上,这些操作比访问局部变量或直接量需要更长的时间。

示例2

在上面代码中,每次循环都查找 items.length,这是一种浪费,因为该值在循环体执行过程中不会改变,因此产生了不必要的性能损失。可以简单的将此值存入一个局部变量中,在控制条件中使用这个局部变量,从而提高循环性能。

  • for (var i = 0;len = items.length;i < len;i ++) {
  • process(items[i]);
  • }
  • var j = 0,count = items.length;
  • while (j < count) {
  • process(items[j++]);
  • }
  • var k = 0,num = items.length;
  • do {
  • process(items[k++]);
  • } while (k < num);

这些重写后的循环只在循环之前对数组长度进行一次属性查询,使控制条件中只有局部变量参与运算,所以速度更快。

倒序循环

还可以通过改变循环的顺序来提高循环性能。通常,数组元素的处理顺序与任务无关,可以从最后一个开始,直到处理完第一个元素。倒序循环是编程语言中常用的性能优化方法。

示例3

JavaScript 中,倒序循环可以略微提高循环性能。

  • for (var i = items.length;i --) {
  • process(items[i]);
  • }
  • var j = items.length;
  • while (j --) {
  • process(items.[j]);
  • }
  • var k = items.length - 1;
  • do {
  • process(items[k]);
  • } while (k --);

在上面代码中使用了倒序循环,并在控制条件中使用了自减。每个控制条件只是简单地与 0 进行比较。控制条件与 true 值进行比较,任何非零数字自动强制转换为 true,而 0 等同于 false。

实际上,控制条件已经从两次比较减少到一次比较,大幅提高了循环速度。与原始版本相比,现在每次迭代中只进行以下操作。

  • 在控制条件中进行一次比较(i == true)。
  • 一次减法操作(i --)。
  • 一次数组查询(items[i])。
  • 一次函数调用(process(items[i]))。

每次迭代中减少两个操作,如果迭代次数成千上万的增长,那么性能将显著提升。

嵌套设计

循环结构常与分支结构混用在一起,但是如何嵌套就就非常讲究了。

示例4 

在一个循环体内,设计只有在特定条件下才执行循环体。

  • var a = true;
  • for (var b = 1;b < 10 ;b ++) { //循环结构
  • if (a == true) { //条件判断
  • console.log(b);
  • }
  • }

很明显,在这个循环中,if 语句会被反复执行。如果 if 的条件不受循环遍历影响,则不妨采用下面嵌套结构来设计。

  • if (a == true) { //条件判断
  • for (var b = 1; b < 10; b ++ ) { //循环结构
  • console.log(b);
  • }
  • }

这样 if 语句只被循环一次,如果 if 条件不成立,则直接省略 for 语句的执行,从而使程序的执行效率大大提高。但是如果 if 条件表达式受循环结构的制约,就不能采用这种方式。

重复声明

在循环体内经常会存在不必要的重复声明。

示例5

下面示例设计在循环内声明数组。

  • for (var b = 0; b < 10; b ++) { //循环
  • var a = new Array(1,2,3,4,5,6,7,8,9,10); //声明并初始化数组
  • console.log(a[b]);
  • }

如果把声明数组放在循环体外会更高效。

  • var a = new Array(1,2,3,4,5,6,7,8,9,10); //声明并初始化数组
  • for (var b = 0; b < 10; b ++) { //循环
  • console.log(a[b]);
  • }

定义循环变量

对于 for 语句来说,当循环变量仅用于循环控制时,不妨在 for 内定义。

示例6

计算 100 之内数字的和。

  • var s = 0; //声明变量
  • for (var i = 0; i <= 100; i ++) { //循环语句
  • s += i;
  • }
  • console.log(s);

显然下面的做法就不妥当,会增大系统开销。

  • var i = 0; //声明变量
  • var s = 0; //声明变量
  • for (i = 0; i <= 100; i ++) { //循环语句
  • s += i;
  • }
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门