for循环从大往小循环真的更加好吗? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a Javascript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
Javascript 权威指南第 5 版
Closure: The Definitive Guide
jacob
V2EX    Javascript

for循环从大往小循环真的更加好吗?

  •  
  •   jacob 2014-01-30 15:33:36 +08:00 9796 次点击
    这是一个创建于 4300 天前的主题,其中的信息可能已经有所发展或是发生改变。
    我的sublime text3,安装了emmet。输入for时会有自动完成,一共2中

    //这种他叫“改进型内置for循环”

    for (var i = Things.length - 1; i >= 0; i--) {
    Things[i]
    };

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

    第一种和第二种在我眼中无非是顺序的区别,请问第一种真的比第二种好吗?
    25 条回复    1970-01-01 08:00:00 +08:00
    qiukun
        1
    qiukun  
       2014-01-30 15:36:45 +08:00
    区别在于 .length ,第一种不会比第二种差,这个理由足够吗?
    rankjie
        2
    rankjie  
       2014-01-30 15:36:46 +08:00 via iPhone
    容易发现的一点是.length不用每次都去计算这点好,其它的请楼下讲讲
    c742435
        3
    c742435  
       2014-01-30 15:37:06 +08:00   1
    真的好。访问0比访问Things.length快多了。第一种只访问了一次,第二种循环几次就放问了几次。
    但是,现在这个时代,再加上会问出这种问题的你所在的编程环境,我觉得真没必要抠这点效率。
    我一般都会写第二种,实在觉得慢,就加一个临时变量缓存下length的值。
    bcxx
        4
    bcxx  
       2014-01-30 15:37:26 +08:00
    dom 元素 collection 的时候每个 length 都要重新遍历容器的……
    czheo
        5
    czheo  
       2014-01-30 15:40:01 +08:00   1
    第一种只有初始化var i= Things.length的时候读取Things.length。
    第二种每跑一个循环都有要做i < Things.length的判断,每次都要读取Things.length,效率略低一点。
    估计是这个区别。
    c742435
        6
    c742435  
       2014-01-30 15:40:08 +08:00   1
    还有,我个人会用for each 以及 for each in。
    其实就是老子高兴用哪个用哪个啦。
    xxr3376
        7
    xxr3376  
       2014-01-30 16:02:25 +08:00   2
    我觉得楼主可能会喜欢这个:http://jsperf.com/fors-vs-while/10 ,js中各种循环方式的测速。
    Crossin
        8
    Crossin  
       2014-01-30 16:57:22 +08:00
    除去不用每次调用.length外(其实这个的实际影响应该很小吧)
    在某些情况下,比如Things是个链表,而你要在循环过程中删除Things中的部分元素,从小到大就会出错,而从大到小不会
    rannnn
        9
    rannnn  
       2014-01-30 17:12:51 +08:00   1
    其实编译器应该吧第二种的length优化到外面去
    alexrezit
        10
    alexrezit  
       2014-01-30 17:51:55 +08:00
    @qiukun
    速度差很多.
    zhujinliang
        11
    zhujinliang  
       2014-01-30 17:53:50 +08:00 via iPad
    这要是在c语言上又会牵扯出等于0判断与等于某值判断速度快慢,volatile关键字,乃至编译器优化的问题
    alexrezit
        12
    alexrezit  
       2014-01-30 18:02:12 +08:00
    @rannnn
    Naive. What if array got modified in loop?
        13
    reusFork  
       2014-01-30 18:03:30 +08:00
    @rannnn 除非编译器能确定length不会变,否则不可能做这样的优化
    Narcissu5
        14
    Narcissu5  
       2014-01-30 18:12:23 +08:00
    犀牛书里面有讲过这个问题,实际上数组的长度是由最后一个不为undefined的元素位置决定的,所以:

    1、计算length很低效,别忘了这是循环,效率差异会被放大
    2、遍历的过程中,数组的长度是可能变化的。估计解释器不会在这里优化。
    dorentus
        15
    dorentus  
       2014-01-30 18:21:18 +08:00   2
    我更喜欢这样:
    for (var i = 0, n = things.length; i < n; ...
    alexrezit
        16
    alexrezit  
       2014-01-30 20:08:50 +08:00
    @dorentus
    Caching length 有个问题就是如果 array 可能在 loop 中 length 改变就不适用了.
    zythum
        17
    zythum  
       2014-01-30 20:14:20 +08:00
    其实 Things.length 是取length这个属性的get方法。这个方法是需要耗时的。
    luikore
        18
    luikore  
       2014-01-30 21:30:29 +08:00
    换在二十年前是会快
    lsylsy2
        19
    lsylsy2  
       2014-01-30 22:09:18 +08:00
    第一反应是Cache DRAM的机制……
    抬头一看Javascript……那应该是Length的判断机制更重要
    slowman
        20
    slowman  
       2014-01-31 01:24:08 +08:00
    http://jsperf.com/fors-vs-while/77
    效率最高的竟然是会破坏数据的 pop 和 shift!
    有比较了解的能讲一下吗?
    cassyfar
        21
    cassyfar  
       2014-01-31 01:54:43 +08:00
    @alexrezit
    for (var i = Things.length - 1; i >= 0; i--) 这种写法也不能处理length在loop里被改变的情况吧
    vellow
        22
    vellow  
       2014-02-01 21:40:18 +08:00 via iPhone
    for(var i=Things.length;i;i--){
    Things[i]
    }
    这种会快一点吗?
    miniwade514
        23
    miniwade514  
       2014-02-07 02:09:43 +08:00 via Android
    不考虑数组长度变化的情况,第一种肯定更快。不用每次都获取长度,和0比大小是最快的。但是对于js而言,不同的引擎或许有不同的解释方法。

    如果只考虑纯粹的数组,可能感觉不到效率差异,但是如果循环内部有dom操作,效率差异会大很多。
    miniwade514
        24
    miniwade514  
       2014-02-07 02:18:51 +08:00 via Android
    @miniwade514 刚才我回复的第二段自己回头看都迷糊了。。当我没说。。晚睡伤脑。。
    yyx990803
        25
    yyx990803  
       2014-02-19 00:16:25 +08:00
    大部分情况下,你在每个循环内所做的具体事情(操作数组或是DOM)花费的时间远远大于执行循环本身花费的时间。这种优化在实际应用中是难以量化的,除非你写的是效率要求特别高的底层基础架构,否则不必太过纠结。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2182 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 01:01 PVG 09:01 LAX 17:01 JFK 20:01
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86