V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
Tsccai
V2EX  ›  JavaScript

请各位大佬赐教,这样的代码该如何优化?

  •  
  •   Tsccai · 2024-02-08 15:42:51 +08:00 · 2281 次点击
    这是一个创建于 369 天前的主题,其中的信息可能已经有所发展或是发生改变。

    目前代码如下

    for(let i=0;i<length;i++) {
        if(flag()){
            foo();
        }
        bar();
    }
    

    简单来说,就是在循环中每次都会去判断一个条件,用来确定是否需要多一步操作。但实际上这个条件是在循环开始前就已经可以确定的了。 这样的代码还可以进一步优化吗?目前想到的是根据条件拆成两个循环,但循环内的代码又高度重复了。

    12 条回复    2024-02-09 15:30:36 +08:00
    hundandadi
        1
    hundandadi  
       2024-02-08 16:00:39 +08:00
    1. flag() 如果与 i 有关
    2.bar()是否有执行条件

    这写的不是挺好的吗。清晰明了。flag() 如果与 i 有关那就没啥问题,bar()是否有执行条件
    crayygy
        2
    crayygy  
       2024-02-08 16:03:02 +08:00 via iPhone
    我记得以前测试过,分成两个循环分别调用不同的处理效率可能更高,再就是 flag() 函数如果是一个确定且和 i 没关系的话,可以用一个变量来代替,避免重复计算
    luoshuitianyi
        3
    luoshuitianyi  
       2024-02-08 16:11:38 +08:00   ❤️ 1
    说实话应该没有更好的办法,效率和代码简洁只能取其一。从逻辑上来讲就是分支放在循环外还是内的问题。

    如果放在内,不论在哪一步都会进行 length 次判断。如果放在外,那在不同分支肯定都要写代码,这就无法保证代码简洁性。

    所以不想因为反复进行条件判断而导致效率降低的话,只能选择后者。
    okakuyang
        4
    okakuyang  
       2024-02-08 16:13:04 +08:00 via iPhone
    没有优化空间
    wangtian2020
        5
    wangtian2020  
       2024-02-08 16:24:02 +08:00
    如果与 i 有关应该没啥性能损失,不需要优化
    如果与 i 无关可以减少不必要的计算
    ```
    let flagTemp = flag()
    for(let i=0;i<length;i++) {
    if(flagTemp){
    foo();
    }
    bar();
    }
    chesha1
        6
    chesha1  
       2024-02-08 20:05:55 +08:00
    你拆成两个,看一下汇编是不是一样就行了,我感觉这么简单的优化,编译器是能做的,自己测试一下呗
    persimmon
        7
    persimmon  
       2024-02-08 20:15:52 +08:00
    depends on 你具体的上下文,foo 和 bar 是不是纯函数? foo 或 bar 执行的时候会不会影响 flag 返回的结果,确定以后再考虑是否单独分出来
    ns09005264
        8
    ns09005264  
       2024-02-08 20:25:06 +08:00
    ```javascript
    let f;
    if (flag()) {
    f = () => {
    foo();
    bar();
    };
    } else {
    f = () => bar();
    }
    for (let i = 0; i < length; i++) {
    f();
    }
    ```
    leonshaw
        9
    leonshaw  
       2024-02-08 21:03:12 +08:00 via Android
    注意 i < length 也判断了 length 次,相信 CPU 的分支预测能力
    Tsccai
        10
    Tsccai  
    OP
       2024-02-08 22:56:21 +08:00
    flag()其实我确实是处理为一个变量,而且它完全不会受到 foo()和 bar()的影响。实际上,这个 flag 在程序最开始执行的时候就已经确定了,它取决于用户的原始输入。
    感谢各位,看来确实是没有多少优化的空间了。
    Al0rid4l
        11
    Al0rid4l  
       2024-02-09 13:21:33 +08:00
    这种时候你需要的是宏这样的东西, 两个循环, 但复用大部分代码
    RecursiveG
        12
    RecursiveG  
       2024-02-09 15:30:36 +08:00
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   6138 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 43ms · UTC 02:07 · PVG 10:07 · LAX 18:07 · JFK 21:07
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.