为什么java里if else比三元运算快??

codeartisan 2007-06-16 04:09:47
我写了两个类来测试速度:

Test:
public class Test {

public static void main(String args[])
{
long time = System.currentTimeMillis();

for(long i=0; i< 2000000000; i++)
{
if(false){String s = null;}
else{String s = null;};
}

System.out.println("'if else':用时"+(System.currentTimeMillis()-time)/1000.0+"秒");
}
}

Test2:


public class Test2 {

public static void main(String args[])
{
long time = System.currentTimeMillis();

for(double i=0; i< 2000000000; i++)
{
String s = false?null:null;
}

System.out.println("'三元运算符':用时"+(System.currentTimeMillis()-time)/1000.0+"秒");
}
}


运行结果if else比三元运算快,试了好几次了,都一样,为什么?
...全文
2805 39 打赏 收藏 转发到动态 举报
写回复
用AI写文章
39 条回复
切换为时间正序
请发表友善的回复…
发表回复
ruixiang123456 2010-12-29
  • 打赏
  • 举报
回复
if else和三元运算要看是在什么样子的情况下作的比较,if else只有在一种情况下是比三元运算要快的。
只有当if下面有多个判断时,它的执行效率就会比三元要快;因为其中的&&符号是起到“短路”的效果,如果if条件中有一个不成立,那么其他的就不会执行。但是如果是三元运算的话,它是会一直的判断的。所以在这种情况下三元要比if else低。

其他的情况我认为都是三元好点的,代码量少又便于理解。。。。
CrazyGou 2007-06-19
  • 打赏
  • 举报
回复
ls是说我吗?

我的那段代码是对比三元运算符和if...else...(sun jdk),而不是试图说明三元运算符如何boxing/unboxing如何convert strong type,三元运算符对这些的处理没什么特别之处

对于其他代码,结果应该是类似的
benq998 2007-06-18
  • 打赏
  • 举报
回复
其实不管源码写成什么样,在javac的时候,都会编程有规律的字节码,既然if else和a?b:c都是判断流程控制语句,所以编译以后的结果都是一样的。
benq998 2007-06-18
  • 打赏
  • 举报
回复
片段A:
boolean b = false;
for(int i=0;i<10000;i++){
if(b){
String s = null;
}else{
String s = null;
}
}
片段B:
boolean b = false;
for(int i=0;i<10000;i++){
String s = b ? null : null;
}
}
反编译片段A和B:
if else a ? b : c
iconst_0 iconst_0
istore_1 istore_1
iconst_0 iconst_0
istore_2 istore_2
iload_2 iload_2
sipush 10000 sipush 10000
if_icmpge 28 if_icmpge 28
iload_1 iload_1
ifeq 20 ifeq 20
aconst_null aconst_null
astore_3 astore_3
goto 22 goto 22
aconst_null aconst_null
astore_3 astore_3
iinc 2, 1 iinc 2, 1
goto 4 goto 4
看看结果应该知道,两段程序对应的字节码是完全一样的,所以运行的时间在理想情况下应该是完全一样的。
gameboy999 2007-06-18
  • 打赏
  • 举报
回复
CrazyZhou的那段字节码不能说明真正问题,因为分析的例子过于简单,

也没指明是sun的jdk还是ibm的jdk...

看看java的specification可以知道,这个三元运算符有点类似于一个函数,并且需要处理boxing/unboxing..

由此看来,根据不同的strong type,编译出来的结果应该是大不一样的.

Conditional Operator ? :
The conditional operator ? : uses the boolean value of one expression to decide which of two other expressions should be evaluated.
The conditional operator is syntactically right-associative (it groups right-to-left), so that a?b:c?d:e?f:g means the same as a?b:(c?d:(e?f:g)).



ConditionalExpression:
ConditionalOrExpression
ConditionalOrExpression ? Expression : ConditionalExpression

The conditional operator has three operand expressions; ? appears between the first and second expressions, and : appears between the second and third expressions.
The first expression must be of type boolean or Boolean, or a compile-time error occurs.

Note that it is a compile-time error for either the second or the third operand expression to be an invocation of a void method. In fact, it is not permitted for a conditional expression to appear in any context where an invocation of a void method could appear (§14.8).

The type of a conditional expression is determined as follows:


If the second and third operands have the same type (which may be the null type), then that is the type of the conditional expression.
If one of the second and third operands is of type boolean and the type of the other is of type Boolean, then the type of the conditional expression is boolean.
If one of the second and third operands is of the null type and the type of the other is a reference type, then the type of the conditional expression is that reference type.
Otherwise, if the second and third operands have types that are convertible (§5.1.8) to numeric types, then there are several cases:
If one of the operands is of type byte or Byte and the other is of type short or Short, then the type of the conditional expression is short.
If one of the operands is of type T where T is byte, short, or char, and the other operand is a constant expression of type int whose value is representable in type T, then the type of the conditional expression is T.
If one of the operands is of type Byte and the other operand is a constant expression of type int whose value is representable in type byte, then the type of the conditional expression is byte.
If one of the operands is of type Short and the other operand is a constant expression of type int whose value is representable in type short, then the type of the conditional expression is short.
If one of the operands is of type; Character and the other operand is a constant expression of type int whose value is representable in type char, then the type of the conditional expression is char.
Otherwise, binary numeric promotion (§5.6.2) is applied to the operand types, and the type of the conditional expression is the promoted type of the second and third operands. Note that binary numeric promotion performs unboxing conversion (§5.1.8) and value set conversion (§5.1.13).
Otherwise, the second and third operands are of types S1 and S2 respectively. Let T1 be the type that results from applying boxing conversion to S1, and let T2 be the type that results from applying boxing conversion to S2. The type of the conditional expression is the result of applying capture conversion (§5.1.10) to lub(T1, T2) (§15.12.2.7).
At run time, the first operand expression of the conditional expression is evaluated first; if necessary, unboxing conversion is performed on the result; the resulting boolean value is then used to choose either the second or the third operand expression:

If the value of the first operand is true, then the second operand expression is chosen.
If the value of the first operand is false, then the third operand expression is chosen.
The chosen operand expression is then evaluated and the resulting value is converted to the type of the conditional expression as determined by the rules stated above. This conversion may include boxing (§5.1.7) or unboxing conversion. The operand expression not chosen is not evaluated for that particular evaluation of the conditional expression.
  • 打赏
  • 举报
回复
没注意这种事,但潜意识里觉得三元至少不可能比if else快。因为if else翻译成机器码时已经无可拆解了,而三元翻译成的结果和if else可能完全一样,至少不可能更快。
gameboy999 2007-06-18
  • 打赏
  • 举报
回复
zapdos() ( ) 信誉:100 Blog 加为好友 2007-6-17 1:06:26 得分: 0



以前好象看过,三元不是短路的,if-else才是,所以呢...



========================

人家都说了,
你写条件的时候,用一个表达式看看

例如 if (obj1.equals(obj2) && i++ != 5 || something )

因为 if 可能是shortcut运算
3元可能不是,而且三元有可能所有结果都要计算(包括2,3元的),但是if如果条件不满足,就不会计算if下面的表达式或语句


不过不清楚是否不同版本的编译器有没有区别

你的测试案例实在太弱了
yougucao379548695 2007-06-18
  • 打赏
  • 举报
回复
哎呀我说呢
Cappuccino_mhc 2007-06-18
  • 打赏
  • 举报
回复
还是程序和判断的少
要是多的话
应该是if else快
codeartisan 2007-06-18
  • 打赏
  • 举报
回复
感谢各位!
chenbojojo 2007-06-18
  • 打赏
  • 举报
回复
又涨了一点见识,谢谢楼上们~
xk2y 2007-06-17
  • 打赏
  • 举报
回复
LZ犯的错啦```
改成同样int就几乎没什么区别了```
numen_wlm 2007-06-17
  • 打赏
  • 举报
回复
又知道了一点!谢谢
hxDreamer 2007-06-17
  • 打赏
  • 举报
回复
在jvm看来应该是一样的,获得十分类似。测试代码其实就是long和double的差别了
iambic 2007-06-17
  • 打赏
  • 举报
回复
有病。
zapdos 2007-06-17
  • 打赏
  • 举报
回复
楼上的同学让我获益非浅
一直以来困扰我的
i=i++
解决了
CrazyGou 2007-06-17
  • 打赏
  • 举报
回复
http://blog.csdn.net/CrazyGou/archive/2007/06/17/1655593.aspx
codeartisan 2007-06-17
  • 打赏
  • 举报
回复
看了。
指令看不懂。
Evwell 2007-06-17
  • 打赏
  • 举报
回复
大家这么测试来测试去没什么意义吧
还是去找找三元运算是怎么在JVM现实的好,
qfs_v 2007-06-17
  • 打赏
  • 举报
回复
if else比三元运算快?不可能!
退一步.这个问题毫无意义!
加载更多回复(19)

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧