V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
Genokiller
V2EX  ›  问与答

Java 中三元和 if else 哪个的效率比较高,有底层解释吗,谢谢了!

  •  
  •   Genokiller · 2018-12-28 17:11:26 +08:00 · 1986 次点击
    这是一个创建于 2153 天前的主题,其中的信息可能已经有所发展或是发生改变。
    7 条回复    2018-12-28 23:04:04 +08:00
    yrom
        1
    yrom  
       2018-12-28 17:24:50 +08:00
    给你个思路,javap 看一下两者编译后的字节码有何不同
    naix1573
        2
    naix1573  
       2018-12-28 17:29:42 +08:00
    三元的效率更高吧
    Genokiller
        3
    Genokiller  
    OP
       2018-12-28 17:46:28 +08:00
    @yrom 我看到有人编译过了,if else 就多了一条 astore 指令,应该是没有影响的
    IsaacYoung
        4
    IsaacYoung  
       2018-12-28 17:47:08 +08:00 via iPhone
    我猜一样都是 jmp?🌹🐔
    shintendo
        5
    shintendo  
       2018-12-28 17:51:49 +08:00   ❤️ 2
    三元总可以转换为等价的 if else 吧,所以如果 if else 效率更高,编译器为什么不做这个转换来优化呢
    Genokiller
        6
    Genokiller  
    OP
       2018-12-28 18:16:11 +08:00
    是否还有其他影响效率的地方


    两段简短的测试代码:

    Test2.java (三元运算符)
    public class Test2
    {
    public static void main(String args[])
    {
    int m =1, n=2;
    String s = m > n ? "a" : "b";
    }
    }



    Test3.java ( if...else...)
    public class Test3
    {
    public static void main(String args[])
    {
    int m = 1, n = 2;
    if(m > n) {
    String s = "a";
    }
    else {
    String s = "b";
    }
    }
    }



    编译后用 javap 反编译得到下面指令码:

    Compiled from "Test2.java"
    public class Test2 extends java.lang.Object{
    public Test2();
    Code:
    0: aload_0
    1: invokespecial #1; //Method java/lang/Object."<init>":()V
    4: return

    public static void main(java.lang.String[]);
    Code:
    0: iconst_1
    1: istore_1
    2: iconst_2
    3: istore_2
    4: iload_1 <-- 变量表索引 1 处的值压入堆栈,即 m 的值 1
    5: iload_2 <-- 变量表索引 2 处的值压入堆栈,即 n 的值 2
    6: if_icmple 14 <-- 比较上面两个值,若 true 继续,否则跳转到 14
    9: ldc #2; //String a <-- load constant,将"a"压入堆栈
    11: goto 16
    14: ldc #3; //String b <-- 将"b"压入堆栈
    16: astore_3 <-- 从堆栈弹出值,存储到变量表索引 3 处
    17: return

    }

    ----------------------------------------

    Compiled from "Test3.java"
    public class Test3 extends java.lang.Object{
    public Test3();
    Code:
    0: aload_0
    1: invokespecial #1; //Method java/lang/Object."<init>":()V
    4: return

    public static void main(java.lang.String[]);
    Code:
    0: iconst_1
    1: istore_1
    2: iconst_2
    3: istore_2
    4: iload_1
    5: iload_2
    6: if_icmple 15
    9: ldc #2; //String a
    11: astore_3
    12: goto 18
    15: ldc #3; //String b
    17: astore_3
    18: return

    }
    ---------------------
    作者:crazygou
    来源:CSDN
    原文: https://blog.csdn.net/CrazyGou/article/details/1655593
    版权声明:本文为博主原创文章,转载请附上博文链接!
    mxalbert1996
        7
    mxalbert1996  
       2018-12-28 23:04:04 +08:00 via Android
    人生三大错觉:我比写编译器的人聪明
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5067 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 09:43 · PVG 17:43 · LAX 01:43 · JFK 04:43
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.