V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Asimov01
V2EX  ›  Java

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

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

    突然想到一个问题,在 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!
    boywang004
        8
    boywang004  
       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   ·   实用小工具   ·   5955 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 03:21 · PVG 11:21 · LAX 19:21 · JFK 22:21
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.