Java 其中";如果;构造更快-语句还是三元运算符?

Java 其中";如果;构造更快-语句还是三元运算符?,java,performance,if-statement,shorthand,premature-optimization,Java,Performance,If Statement,Shorthand,Premature Optimization,java-classic中有两种类型的if语句:if{}else{}和速记:exp?值1:值2。一个比另一个快还是一样 声明: int x; if (expression) { x = 1; } else { x = 2; } 三元运算符: int x = (expression) ? 1 : 2; 两者都不是-它们将编译为相同的字节码。您的两个示例都可能编译为相同或几乎相同的字节码,因此性能应该没有差异 如果执行速度有所不同,您仍然应该使用最惯用的版本(第二个版本用于根据简单条件和

java-classic中有两种类型的
if
语句:
if{}else{}
和速记:
exp?值1:值2
。一个比另一个快还是一样

声明:

int x;
if (expression) {
  x = 1;
} else {
  x = 2;
}
三元运算符:

int x = (expression) ? 1 : 2;

两者都不是-它们将编译为相同的字节码。

您的两个示例都可能编译为相同或几乎相同的字节码,因此性能应该没有差异


如果执行速度有所不同,您仍然应该使用最惯用的版本(第二个版本用于根据简单条件和两个简单子表达式分配单个变量,第一个版本用于执行更复杂的操作或不适合单行的操作)

这些都是一样的。它们都相当快,通常在10-30纳秒左右。(取决于使用模式)此时间段对您重要吗

你应该做你认为最清楚的事情。

这里只有一种类型的“如果”陈述。另一个是条件表达式。至于哪一个性能更好:它们可以编译成相同的字节码,我希望它们的行为相同——或者非常接近,以至于在性能方面你肯定不想选择其中一个

有时,
if
语句更可读,有时条件运算符更可读。特别是,我建议在两个操作数简单且无副作用时使用条件运算符,而如果两个分支的主要用途是它们的副作用,我可能会使用
if
语句

下面是一个示例程序和字节码:

public class Test {
    public static void main(String[] args) {
        int x;
        if (args.length > 0) {
            x = 1;
        } else {
            x = 2;
        }
    }

    public static void main2(String[] args) {
        int x = (args.length > 0) ? 1 : 2;
    }
}
使用
javap-c测试反编译字节码

public class Test extends java.lang.Object {
  public Test();
    Code:
       0: aload_0
       1: invokespecial #1
       4: return

  public static void main(java.lang.String[]
    Code:
       0: aload_0
       1: arraylength
       2: ifle          10
       5: iconst_1
       6: istore_1
       7: goto          12
      10: iconst_2
      11: istore_1
      12: return

  public static void main2(java.lang.String[
    Code:
       0: aload_0
       1: arraylength
       2: ifle          9
       5: iconst_1
       6: goto          10
       9: iconst_2
      10: istore_1
      11: return
}

正如你所看到的,字节码在这里有一个细微的差别——不管
历史记录是否发生在分支中(与我之前有严重缺陷的尝试不同:),但如果抖动以不同的本机代码结束,我会非常惊讶。

只是为了补充所有其他答案:


第二个表达式通常称为三级/三值运算符/语句。它可能非常有用,因为它返回一个表达式。有时,对于典型的简短语句,它会使代码更清晰。

三元运算符比if-else条件更快

public class TerinaryTest {
    public static void main(String[] args)
    {
        int j = 2,i = 0;
        Date d1 = new Date();
        for(long l=1;l<100000000;l++)
            if(i==1) j=1;
                else j=0;
        Date d2 = new Date();
        for(long l=1;l<100000000;l++)
            j=i==1?1:0;
        Date d3 = new Date();
        System.out.println("Time for if-else: " + (d2.getTime()-d1.getTime()));
        System.out.println("Time for ternary: " + (d3.getTime()-d2.getTime()));
    }
}
公共类TerinaryTest{
公共静态void main(字符串[]args)
{
int j=2,i=0;
日期d1=新日期();

对于(长l=1;我猜这绝对没有区别。只是语法。除非编译器有点邪恶(或其他东西),我错了,对吗(micro)基准测试?分享结果。两者都会得到jit'ed。不会有任何区别。而且不要费心去反编译这些东西。HotSpot做的第一件事就是去掉javac应用的所有优化。它们不是以不同的速度存在的。它们是为不同的目的而存在的。我相信你理解各州之间的区别ts和表达式。语句执行操作。表达式生成值。
如果
用于语句。
用于表达式。+1因为对这个问题的回答值得一读,即使原始问题的意图是错误的。s/conditional statement/conditional expression/我猜你不是指f或者
main
main2
完全相同?令人印象深刻。我直到现在才知道你可以编译字节码。@Kyle:我编译了Java,然后用javap反编译。@Kyle:完全一样。我原以为字节码是一样的。事实上,它几乎是一样的:)这在实践中是一个很好的例子:在Java中,如果我必须根据表达式的结果生成一个字符串final,我可以使用三元语法final String,它的table=(Integer.parseInt(clientId)>500)?“serverClients”:“offlineClients”;然后我可以在需要最终表的位置使用表达式的值。以下内容将是非法的:最终字符串whichTable=“”;if(Integer.parseInt(clientId)>500){whichTable=“serverClients”;}else{whichTable=“offlineClients”;}@jamesperich在
final
字段的情况下,可以使用构造函数块来设置值(尽管条件运算符看起来比IMO好10亿倍),并且对于局部变量,您可以在以后的代码块中第一次使用之前分配一个值。我认为三元数比
if else
更具优势的唯一情况是调用
super(…)
this(…)
在构造函数中。我在运行示例时得到了完全相反的结果,这表明结果是不可靠的。不幸的是,您陷入了微基准标记陷阱——要正确地进行微基准标记是出了名的困难。对于几个示例,您可以在这里看到:您的特定示例至少受到这些问题的影响问题:4次测试是远远不够的,您总是以相同的顺序运行测试(第一次,如果有,第二次),在运行测试之前不预热JVM,等等。