问题

缓存 Array.length 是老生常谈的小优化。

// 不缓存
for (var i = 0; i < arr.length; i++) {
...
} // 缓存
var len = arr.length;
for (var i = 0; i < len; i++) {
...
} // 或者
for (var i = 0, len = arr.length; i < len; i++) {
...
}

但以前写过 Java 的笔者一直对这种破碎的写法感到不适,也对这种写法的实际优化效果产生疑问。

且推崇这种写法的朋友似乎很多也是“前辈这么说+自己想了一下觉得有道理”。

由于 for 循环搭配 Array.length 是极度常用的 JavasScript 代码,所以还是有必要搞清楚的。

结论

经过一番摸索后笔者得到的结论是:缓存 Array.lengh 对优化的影响没有想象中的大,甚至可能会有所减慢。

理由

从测试结果上看

stackoverflow 上也有这个讨论,For-loop performance: storing array length in a variable 。

accepted 的答案是说缓存会起到加速的结果,给出了 jsPerf 测试。

但是有答案反对,也给出了 jsPerf 测试。

两个答案的区别在于“循环不变量代码移动(Loop-invariant code motion)”,accepted 答案的测试循环里没有访问到数组,是不实际的,后面会讲到。

从另一篇文章 Shoud I have to cache my array’s length? 的测试结果也可以看出缓存差别不大。

还有这篇 JavaScript's .length Property is a Stored Value

从 V8 的中间代码分析

这篇文章 How the Grinch stole array.length access 从 V8 的 hydrogen 探讨 Array.length 在 for 循环中的处理。

正如上面提到的“循环不变量代码移动”,V8 引擎会聪明的把能确定不变的代码移到循环外。

所以像下面这种代码也不会影响引擎对 Array.length 的优化:

function uncached(arr) {
for (var i = 0; i < arr.length; i++) {
arr[i]
}
}

而当在循环中调用函数时,V8 会尝试将函数进行内联,从而继续进行“循环不变量代码移动”优化。
但当函数不可内联时,V8 就没辙了,每次循环都要重新计算一遍 length

function BLACKHOLE(sum, arr) {
try { } catch (e) { }
} function uncached(arr) {
var sum = 0;
for (var i = 0; i < arr.length; i++) {
sum += arr[i];
if (sum < 0) BLACKHOLE(arr, sum);
}
return sum;
}

但这时即便是在循环外缓存了 length 也是没有用的,引擎没法预判数组的变化,当需要访问数组元素时会触发 bounds check ,从而照样要计算一遍 length 。所以缓存 length 是没有用的。

甚至,由于多了一个变量,底层的寄存器分配器每次循环还要多一次恢复这个变量。当然这个只有在大规模的情况下才会看出区别。

结尾

当然这篇文章也有局限性,仅仅讨论了 V8 引擎,也没有讨论访问 length 代价更高的 HTMLCollection 。但这已经足够说明两者差别不大,一般情况下我们不用再局限于缓存的写法,可以放开来按照自己喜欢的方式去写循环了。

【完】

原文:http://div.io/topic/966

缓存 Array.length 是老生常谈的小优化的更多相关文章

  1. check the element in the array occurs more than half of the array length

    Learn this from stackflow. public class test { public static void main(String[] args) throws IOExcep ...

  2. [Bug]The maximum array length quota (16384) has been exceeded while reading XML data.

    写在前面 在项目中,有客户反应无法正常加载组织结构树,弄了一个测试的程序,在日志中查看到如下信息: Error in deserializing body of reply message for o ...

  3. SPFA 小优化*2

    /* bzoj 2763 SPFA小优化 循环队列+SLF 顺面改掉自己之前手打qeueu的坏毛病*/ #include<iostream> #include<cstring> ...

  4. Array.length vs Array.prototype.length

    I found that both the Array Object and Array.prototype have the length property. I am confused on us ...

  5. 【转】The magic behind array length property

    Developer deals with arrays every day. Being a collection, an important property to query is the num ...

  6. [MySQL5.6] 最近对group commit的小优化

    [MySQL5.6] 最近对group commit的小优化 http://www.tuicool.com/articles/rEZr2q 最近花了一些时间在做MySQL Group Commit的优 ...

  7. Count and Say (Array Length Encoding) -- LeetCode

    The count-and-say sequence is the sequence of integers beginning as follows:1, 11, 21, 1211, 111221, ...

  8. SPFA的小优化

    标签:闲扯 SPFA的小优化 1. 向队尾加入元素时,如果它比对首还优,就把把它直接和队首交换. 拿一个双端队列来实现 (手写 , head ,tail   STLdeque亲测及其慢) 这个小优化其 ...

  9. Math.floor(Math.random() * array.length),splice

    1.Math.floor(Math.random() * array.length) 返回长度内的索引 eg: changeLimit () { function getArrayItems(arr, ...

随机推荐

  1. kettle工具同步数据乱码-Linux下乱码问题二

    将写好的kettle工程部署到Linux下后,同步的数据都成了乱码,幸运的是数据库有备份. 下面就说一下,kettle工程如何同步两端编码格式都是utf8的数据库. 我们只需要更改kettle数据库连 ...

  2. CentOS6.5下解压文件.tar.gz .war .zip

    解压.tar.gz文件: tar -zxvf web.tar.gz tar不支付解压文件到指定的文件夹! 解压.war .zip文件到指定文件夹: unzip web.war -d webapps/R ...

  3. 生成ssl证书文件

    网上关于生成SSL证书文件的方法有很多,但我查了几个,发现有或多或少的错误,如下我图文并茂的展示,亲测无任何问题,分享给大家,谢谢. 1.创建根证书密钥文件(自己做CA)root.key openss ...

  4. Hacker(三)之黑客定位目标---IP

    IP即Internet Protocol的简称,中文简称"网协",是为计算机网络相互连接进行通信而设计的协议.无论何种操作系统,只要遵守IP协议就可以与Internet互联互通. ...

  5. 【水题递归】【HDU2044】我大沙茶了

    有一只经过训练的蜜蜂只能爬向右侧相邻的蜂房,不能反向爬行.请编程计算蜜蜂从蜂房a爬到蜂房b的可能路线数. 其中,蜂房的结构如下所示.   Input 输入数据的第一行是一个整数N,表示测试实例的个数, ...

  6. 数据结构算法应用C++语言描述——(1)C++基础知识

    一.二维数组 (1)二维数组的列是固定时,行未知时使用动态分配 当一个二维数组每一维的大小在编译时都是已知时,可以采用类似于创建一维数组的语法 来创建二维数组.例如,一个类型为char的7×5数组可用 ...

  7. <转>让SVN用户能够修改自身密码的PHP页面

    1.修改Apache配置文件因为我在安装和配置SVN的时候,对Apache的配置文件进行过优化,将所有关于SVN的配置都写在了/opt/apache2/conf/extra/httpd-svn.con ...

  8. W - stl 的 优先队列 Ⅲ

    Description In a speech contest, when a contestant finishes his speech, the judges will then grade h ...

  9. Apache+tomcat的整合

    http://blog.csdn.net/stefyue/article/details/6918542 为什么要做这个整合呢?当然,首先想到是就是Apache和Tomcat的区别.正因为有区别,有各 ...

  10. ASCII码排序,hdu-2000

    Problem Description 输入三个字符后,按各字符的ASCII码从小到大的顺序输出这三个字符.   Input 输入数据有多组,每组占一行,有三个字符组成,之间无空格.   Output ...