这种循环判断如何优化呢 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a Javascript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
Javascript 权威指南第 5 版
Closure: The Definitive Guide
xxxpara
V2EX    Javascript

这种循环判断如何优化呢

  •  
  •   xxxpara 2015-03-20 10:31:24 +08:00 4685 次点击
    这是一个创建于 3876 天前的主题,其中的信息可能已经有所发展或是发生改变。

    for(x=0;x<8;x++){
    if(x==0||x==8){
    y=1;
    }
    if(x==1||x==7){
    y=2;
    }
    if(x==2||x==6){
    y=4;
    }
    else{
    y=6;
    }
    for(y;y<6;y++)
    {
    //...
    }
    }

    15 条回复    2015-03-21 18:03:58 +08:00
    xylophone21
        1
    xylophone21  
       2015-03-20 10:58:07 +08:00
    "优化"的目的是什么?
    代码好看还是性能? 前者可以查表,后者忘了吧.
    Magic347
        2
    Magic347  
       2015-03-20 11:19:36 +08:00   4
    方案一:预置一个类似映射关系的数组,计算过程直接读取
    int Y[8] = {1, 2, 4, 6, 6, 6, 4, 2, 1}
    for (int x = 0; x < 8; x++) {
    int y = Y[x];
    }

    方案二:尝试建立动态的映射关系,计算过程中动态执行计算
    int Y(int x) {
    if (0 <= (x%8) && (x%8) <= 2) {
    return power(2, x%8);
    }
    return 6;
    }
    for (int x = 0; x < 8; x++) {
    int y = Y(x);
    }

    以上,就是简单的两种思路吧,
    方案一基于空间换时间的思想,
    可以节省相应的映射计算开销,保证较好的查询效率;

    方案二基于时间换空间的思想,
    如果可以找到比较高效的映射函数,
    一方面不会浪费存储资源,另一方面也可以实现较好的执行效率
    c742435
        3
    c742435  
       2015-03-20 11:25:15 +08:00
    另外,如果使用switch-case 而不是连续的if,编译器会帮你创建楼上方案1的那种优化方式。
    xxxpara
        4
    xxxpara  
    OP
       2015-03-20 11:28:27 +08:00
    @Magic347 受教!
    zhicheng
        5
    zhicheng  
       2015-03-20 11:42:25 +08:00
    switch-case 大法好。C 语言里边最高级的表达式。

    switch (x) {
    case 0:
    case 8:
    y = 1;
    break;
    case 1:
    case 7:
    y = 2;
    break;
    case 2:
    case 6:
    y = 4;
    break;
    default:
    y = 6;
    break;
    }

    for (; y < 6; y++) {
    }
    }
    miterleo
        6
    miterleo  
       2015-03-20 11:52:27 +08:00
    @Magic347 方案二 (6 % 8 = 6)、(7 % 8 = 7)
    drivedreams
        7
    drivedreams  
       2015-03-20 12:27:29 +08:00
    很显然要用switch
    haitongz
        8
    haitongz  
       2015-03-20 12:37:23 +08:00
    switch吧
    luw2007
        9
    luw2007  
       2015-03-20 13:30:37 +08:00
    数组: [0, 1, 2, 3, 4, 5, 6, 7, 8]
    1.=> [0, 1, 2, 3, 4, 3, 2, 1, 0] <= 按照下标5做镜像. f(y) = 4-|x-4|, 得到
    2.=> [1, 2, 4, 8, 16, 8, 4, 2, 1] <= 按照需求做指数曲线 f(y) = 2 ** x

    判断小于6 其实就是判断第一步中元素小于3.
    由 f(y) < 3 得 4-|x-4| < 3, 进而得到 x> 5, 或者x<3 成立.
    综上可得:

    if (x<3 || x>5){
    // 分开写可以简化绝对值
    y = 2 ** (4-|x-4|)
    }else{
    y = 6
    }

    使用switch也可以.
    guoguoer
        10
    guoguoer  
       2015-03-20 14:03:09 +08:00
    支持 @Magic347 的方法1,
    在输入和输出的数量有限的情况下,先做一次预计算,把表算出来。之后都查表。
    otakustay
        11
    otakustay  
       2015-03-20 15:04:01 +08:00
    我来给你们展示下不可读的优化:

    function for1() {}
    function for2() {}
    function for3() {}

    var tasks = [for1, for2, for3, for3, for2, for1];
    for (var i = 0; i < 8; i++) {
    tasks[i]();
    }
    Magic347
        12
    Magic347  
       2015-03-20 16:59:10 +08:00
    @miterleo 多谢指正,粗心大意了 :)
    @xxxpara 方案二的Y()可能实现的有些小问题,简单更正一下,

    int Y(int x) {
    if (6 <= x && x <= 8) {
    x = 8 - x;
    }
    if (0 <= x && x <= 2) {
    return power(2, x);
    }
    return 6;
    }
    Magic347
        13
    Magic347  
       2015-03-20 17:08:31 +08:00
    @xxxpara 另外数组应该至少有9个元素,外部x迭代值的边界条件也需要更正一下,再次更正一下两个方案 :)

    方案一:
    int Y[9] = {1, 2, 4, 6, 6, 6, 4, 2, 1}

    for (int x = 0; x < 9; x++) {
    int y = Y[x];
    // do something else
    }


    方案二:
    int Y(int x) {
    if (6 <= x && x <= 8) {
    x = 8 - x;
    }
    if (0 <= x && x <= 2) {
    return power(2, x);
    }
    return 6;
    }

    for (int x = 0; x < 9; x++) {
    int y = Y(x);
    // do something else
    }
    br00k
        14
    br00k  
       2015-03-20 17:19:03 +08:00
    这种自然建议switch,代码可读性也高很多。
    libook
        15
    libook  
       2015-03-21 18:03:58 +08:00
    我第一眼也是想到了switch。
    其实你要说明优化的方向,是可读性还是存储还是计算?
    其实用Javascript这么高级的语言,个人的观点是可读性比性能重要,所以优化主要是在可读性上优化,你的代码用switch就会有很好的可读性,容易维护。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3376 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 30ms UTC 04:57 PVG 12:57 LAX 21:57 JFK 00:57
    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