探讨一下 [if..else] 语句在 Java 和 JavaScrip 中的效率问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Asimov01
V2EX    Java

探讨一下 [if..else] 语句在 Java 和 JavaScrip 中的效率问题

  •  
  •   Asimov01 2018-03-29 15:03:37 +08:00 5086 次点击
    这是一个创建于 2755 天前的主题,其中的信息可能已经有所发展或是发生改变。

    突然想到一个问题,在 Java 中

    if(a > 1){ return 2; }else { return 0; } 

    if(a > 1){ return 2 } retrun 0; 

    这两种写法最终的效果是一样的,那么效率也是一样的吗?
    在 Javascript 中呢?

    42 条回复    2018-03-29 23:51:51 +08:00
    airport0930
        1
    airport0930  
       2018-03-29 15:06:42 +08:00   1
    今晚吃什么?
    zhlssg
        2
    zhlssg  
       2018-03-29 15:11:20 +08:00
    ......一般来说,优先选择第二种。但是肯定不是出于考量效率的角度
    zwx327634
        3
    zwx327634  
       2018-03-29 15:15:21 +08:00   1
    我的习惯是,每个 if,都要有个 else 结尾,可读性强,业务上也减少遗漏问题。代码审查会度量 if 里的条件数量,else 不知道
    shintendo
        4
    shintendo  
       2018-03-29 15:15:41 +08:00
    如果两种写法是等价的,而写法 A 效率更高,那编译器为什么不把写法 B 自动优化成写法 A 呢
    we2ex
        5
    we2ex  
       2018-03-29 15:18:55 +08:00 via Android
    分支预测 了解一下
    we2ex
        6
    we2ex  
       2018-03-29 15:22:49 +08:00 via Android
    又想起了这个帖子 /t/441435
    araraloren
        7
    araraloren  
       2018-03-29 15:36:33 +08:00
    Your question is too simple!
    vela
        8
    vela  
       2018-03-29 15:39:58 +08:00
    @zhlssg Java 选一……和执行效率无关,而是可读性和可维护性考虑。
    sdpfoue
        9
    sdpfoue  
       2018-03-29 15:45:44 +08:00
    影响效率的地方千千万 唯独不需要考虑你提的这种东西
    learnshare
        10
    learnshare  
       2018-03-29 15:49:01 +08:00
    编译器会考虑这些问题,并不是写代码的时候该操的心
    jmc891205
        11
    jmc891205  
       2018-03-29 15:51:16 +08:00
    Java 和 Javascript 我不知道
    但是在 C++里编译器会把他们优化成同样的东西
    mokeyjay
        12
    mokeyjay  
       2018-03-29 16:00:15 +08:00
    js 的话,理论上第二种性能高一点吧
    但这根本就能忽略不计,毫无意义
    zhlssg
        13
    zhlssg  
       2018-03-29 16:14:38 +08:00
    @boywang004 好吧,我是写 js 的,airbnb 的 eslint 约束规则是必须用第二种
    autoxbc
        14
    autoxbc  
       2018-03-29 16:48:05 +08:00
    用 node 跑了一下,没有区别

    习惯上用第二种;多个特例的话,第一种会出魔鬼三角
    flowfire
        15
    flowfire  
       2018-03-29 16:52:40 +08:00
    卫语句了解一下
    yejinmo
        16
    yejinmo  
       2018-03-29 16:59:13 +08:00
    大括号不换行影响性能
    xuhaoyangx
        17
    xuhaoyangx  
       2018-03-29 17:00:09 +08:00
    可读性 1 好
    Asimov01
        18
    Asimov01  
    OP
       2018-03-29 17:07:36 +08:00 via Android
    我的习惯是第一种写法,但是看到别人的代码里面有很多第二种写法,个人感觉可读性和维护性是不如第一种写法的。

    所以就突然想到这个问题,这两种写法除了可读性方面的差别,那么在执行效率上会不会有什么差别呢?

    也并不是纠结这个问题,所以说是探讨一下。

    但是如果想劝公司里其他人也改用第一种写法(保持公司代码风格一致性),除了可读、可维护性更好,如果效率也更高,那么理由也就更充分一些。
    Asimov01
        19
    Asimov01  
    OP
       2018-03-29 17:09:59 +08:00 via Android
    @flowfire 不是什么情况都适合卫语句的,分支少,嵌套层级少的情况下,有什么必要用卫语句呢
    sw0rd3n
        20
    sw0rd3n  
       2018-03-29 17:10:47 +08:00 via iPhone
    编译器会优化的,两种写法等价
    Asimov01
        21
    Asimov01  
    OP
       2018-03-29 17:10:50 +08:00 via Android
    @sdpfoue 这倒是,不过我也不是纠结这个问题,只是突然想到,就抛出来讨论一下
    Asimov01
        22
    Asimov01  
    OP
       2018-03-29 17:16:09 +08:00 via Android
    @we2ex 从社会效率角度来讲,装配工确实不需要了解发动机原理,但从个人的角度来讲,这个装配工可能永远都只能做个装配工了,了不起是个高级装配工。求知欲是个体进步的动力。
    zst
        23
    zst  
       2018-03-29 17:26:13 +08:00 via Android
    我还以为这种问题只会在 Mathematica 里面有
    flowfire
        24
    flowfire  
       2018-03-29 17:37:53 +08:00
    @Asimov01 #19 长的好看
    ppaapc
        25
    ppaapc  
       2018-03-29 18:07:54 +08:00
    java 中肯定第二种吧 不然还得写个 return 跟效率是没啥关系
    wfd0807
        26
    wfd0807  
       2018-03-29 18:17:52 +08:00
    说第一种可读性高的,估计是没见过世面
    我见过的
    if (condition) {
    dosomething
    if (condition) {
    dosomething
    if (condition) {
    dosomething
    if (condition) {
    dosomething
    } else {
    return
    }
    } else {
    return
    }
    } else {
    return
    }
    } else {
    return
    }
    wfd0807
        27
    wfd0807  
       2018-03-29 18:18:12 +08:00
    回帖不能 markdown 吗
    misaka19000
        28
    misaka19000  
       2018-03-29 18:32:13 +08:00   1
    对于 Java8 来说是一样的,因为编译后的字节码完全一样:
    ```
    public int test();
    Code:
    0: iconst_0
    1: istore_1
    2: iload_1
    3: iconst_1
    4: if_icmple 9
    7: iconst_2
    8: ireturn
    9: iconst_0
    10: ireturn

    public int test();
    Code:
    0: iconst_0
    1: istore_1
    2: iload_1
    3: iconst_1
    4: if_icmple 9
    7: iconst_2
    8: ireturn
    9: iconst_0
    10: ireturn
    ```
    zn
        29
    zn  
       2018-03-29 18:44:19 +08:00
    路判断法了解一下?

    ```
    bool processData(int arg1, string arg2, int arg3, SomeObject arg4, ....) {

    if( arg1 < 0 ) {
    return false;
    }
    if( isValid(arg2) ) {
    return false;
    }
    if( arg3 > 99 ) {
    return false;
    }
    if( arg4 == null ) {
    return false;
    }

    ...

    processArg1(arg1);
    processArg2(arg2);

    ...

    return true;
    }
    ```
    aa6563679
        30
    aa6563679  
       2018-03-29 18:44:28 +08:00 via iPhone
    这种小细节没必要在意的,因为编译时编译器会优化,运行时还有 jit 再优化,最终代码不知道变成什么样了
    aristotll
        31
    aristotll  
       2018-03-29 18:59:34 +08:00
    我反而喜欢用三目表达式 ...
    iyangyuan
        32
    iyangyuan  
       2018-03-29 19:17:54 +08:00 via iPhone
    第二种优于第一种,没什么可讨论的
    kisnows
        33
    kisnows  
       2018-03-29 19:47:00 +08:00
    @wfd0807 #26 像你说的这种的话,直接 else 条件判断玩 return 掉,其他的依然有 if 就有 else
    Asimov01
        34
    Asimov01  
    OP
       2018-03-29 21:56:59 +08:00 via Android
    @misaka19000 这就是我想要的东西,用事实说话
    q397064399
        35
    q397064399  
       2018-03-29 22:10:33 +08:00
    @Asimov01 #34 效率在运行时也是不一样的,,了解下 分支预测 跟 指令冒险 还有内存屏障,你就知道 这个代码 在不同场景下 性能是完全两回事了
    loveCoding
        36
    loveCoding  
       2018-03-29 22:22:41 +08:00
    提前判断,提前返回,增加可读性
    Justin13
        37
    Justin13  
       2018-03-29 22:50:16 +08:00 via Android
    喜欢第二种,大括号能省就省,最好是
    return (a > 1 ? 2 : 0)
    aleung
        38
    aleung  
       2018-03-29 22:55:16 +08:00 via Android
    为什么不自己测试一下呢? js 可以用 jsperf.com
    zone53
        39
    zone53  
       2018-03-29 23:07:41 +08:00 via iPhone
    一般来说,函数出口只留一个是最好的吧,所以返回一个变量比较好。
    Asimov01
        40
    Asimov01  
    OP
       2018-03-29 23:36:08 +08:00 via Android
    @q397064399 多谢指教,我去了解了解
    lolizeppelin
        41
    lolizeppelin  
       2018-03-29 23:36:35 +08:00 via Android
    JS 选择第二种规范的原因难道不是为了减少文件大小 233
    q397064399
        42
    q397064399  
       2018-03-29 23:51:51 +08:00
    @Asimov01 #40 谈不上指教,上面很多人 侃侃而谈,,但是都没有说到重点,,一个行 Java 代码从编译到字节码,jvm 自身的优化,然后到 cpu 执行,到指令预测 流水线上取出,查询缓存 ,两三本书都讲不完,,当然有些东西,做应用开发的 不一定要去了解那么深入,以前我的看法就是,这个玩意不就是这样嘛,有什么好神奇的, 当时觉得 Java 内存回收 不就那么回事嘛(不就是分析下有向图的节点是否可达) 看了 G1 回收器 瞬间打脸,然后发下 多线程回收各种细节需要处理,我们做技术的 了解的越多 ,在遇到问题的时候 就会有更多的选择,方案选型的经验就上来了,我是希望做技术的能时刻保持着空杯心态,虚心的去接收别人的意见,去验证 去学习 才能更好的提升自己在技术方面的能力。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     900 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 32ms UTC 21:25 PVG 05:25 LAX 14:25 JFK 17:25
    Do have faith in what you're doing.
    ubao 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