目前代码如下
for(let i=0;i<length;i++) {
    if(flag()){
        foo();
    }
    bar();
}
简单来说,就是在循环中每次都会去判断一个条件,用来确定是否需要多一步操作。但实际上这个条件是在循环开始前就已经可以确定的了。 这样的代码还可以进一步优化吗?目前想到的是根据条件拆成两个循环,但循环内的代码又高度重复了。
|      1hundandadi      2024-02-08 16:00:39 +08:00 1. flag() 如果与 i 有关  2.bar()是否有执行条件 这写的不是挺好的吗。清晰明了。flag() 如果与 i 有关那就没啥问题,bar()是否有执行条件 | 
|  |      2crayygy      2024-02-08 16:03:02 +08:00 via iPhone 我记得以前测试过,分成两个循环分别调用不同的处理效率可能更高,再就是 flag() 函数如果是一个确定且和 i 没关系的话,可以用一个变量来代替,避免重复计算 | 
|      3luoshuitianyi      2024-02-08 16:11:38 +08:00  1 说实话应该没有更好的办法,效率和代码简洁只能取其一。从逻辑上来讲就是分支放在循环外还是内的问题。 如果放在内,不论在哪一步都会进行 length 次判断。如果放在外,那在不同分支肯定都要写代码,这就无法保证代码简洁性。 所以不想因为反复进行条件判断而导致效率降低的话,只能选择后者。 | 
|      4okakuyang      2024-02-08 16:13:04 +08:00 via iPhone 没有优化空间 | 
|  |      5wangtian2020      2024-02-08 16:24:02 +08:00 如果与 i 有关应该没啥性能损失,不需要优化 如果与 i 无关可以减少不必要的计算 ``` let flagTemp = flag() for(let i=0;i<length;i++) { if(flagTemp){ foo(); } bar(); } | 
|      6FlashEcho      2024-02-08 20:05:55 +08:00 你拆成两个,看一下汇编是不是一样就行了,我感觉这么简单的优化,编译器是能做的,自己测试一下呗 | 
|  |      7persimmon      2024-02-08 20:15:52 +08:00 depends on 你具体的上下文,foo 和 bar 是不是纯函数? foo 或 bar 执行的时候会不会影响 flag 返回的结果,确定以后再考虑是否单独分出来 | 
|  |      8ns09005264      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(); } ``` | 
|      9leonshaw      2024-02-08 21:03:12 +08:00 via Android 注意 i < length 也判断了 length 次,相信 CPU 的分支预测能力 | 
|      10Tsccai OP flag()其实我确实是处理为一个变量,而且它完全不会受到 foo()和 bar()的影响。实际上,这个 flag 在程序最开始执行的时候就已经确定了,它取决于用户的原始输入。 感谢各位,看来确实是没有多少优化的空间了。 | 
|  |      11Al0rid4l      2024-02-09 13:21:33 +08:00 这种时候你需要的是宏这样的东西, 两个循环, 但复用大部分代码 | 
|  |      12RecursiveG      2024-02-09 15:30:36 +08:00 Benchmark 表示开了优化没啥区别: https://gist.github.com/RecursiveG/5361f6da8814f3f11bb63581f401cd87 |