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 · 4168 次点击
    这是一个创建于 3538 天前的主题,其中的信息可能已经有所发展或是发生改变。

    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 语言里边最高级的表达式。

    for (x = 0; x < 8; x++) {
    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   ·   实用小工具   ·   1164 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 18:42 · PVG 02:42 · LAX 10:42 · JFK 13:42
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.