Possible Duplicate:
Java: If vs. Switch
For all the conditional statements that are observed in programming, which of these blocks is the most preferred:
- Ternary operator
- else-if block
- switch block
Thanks in advance!
Possible Duplicate:
Java: If vs. Switch
For all the conditional statements that are observed in programming, which of these blocks is the most preferred:
Thanks in advance!
Of course you may implement the comparison in different ways.
I did it this way:
common block:
int a = 42;
int k = 17;
if:
if (a == 42)
k+=4;
else k+=5;
case:
switch (a) {
case 42: k+=4; break;
default: k+=5; break;
}
Ternary:
k += (a == 42) ? 4 : 5;
They don't compile to the same bytecode:
l *Tern*.class
-rw-r--r-- 1 stefan stefan 704 2012-04-27 14:26 CaseIfTern.class
-rw-r--r-- 1 stefan stefan 691 2012-04-27 14:26 IfTernCase.class
-rw-r--r-- 1 stefan stefan 728 2012-04-27 14:26 TernIfCase.class
However, advantages of switch come into play when you have multiple cases - not just 2.
If and ternary get cascading for more than 2 cases.
But they differ idiomatically/semantically. The Ternary operator returns something, but not the if or the switch.
So it isn't that clear what you have to compare.
But I made a benchmark with following result:
0 if tern case
1 3.103 0.244 0.118
2 0.306 0.276 0.309
3 0.382 0.329 0.328
4 0.464 0.435 0.458
5 5.045 1.519 1.248
6 4.57 3.088 2.915
7 4.036 2.977 3.015
8 3.197 3.834 3.893
9 4.631 4.523 5.488
10 6.445 3.891 3.09
Which shows, that they really don't make much difference, and that caching effects have still, for 5 M cases, an influence, even after heating up the VM.
In real circumstances, you rarely have million invocations where nearly nothing happens. But if something happens, the time for if/case/ternary becomes soon irrelevant.
Here is the code I tested:
public class CaseTernIf
{
public static int aORbIf (int a) {
if (a == 2)
return 4;
else return 5;
}
public static int aORbTern (int a) {
return (a == 2) ? 4 : 5;
}
public static int aORbCase (int a) {
switch (a) {
case 2: return 4;
default: return 5;
}
}
}
Here is the Testing code (which is Scala):
object IfCaseTernBench extends Benchcoat [List[Int], Seq[Int]] {
type I=List[Int]
type O=Seq[Int]
val name = "CaseTern"
/** We return a List of random Ints numbers here. */
def iGenerator (n: Int) : I = (for (x <- 1 to n) yield math.abs (random.nextInt (3))).toList
def takePart (li: I, n: Int) : I = li.take (n)
/* Each algorithm is called by a mapping to a static method. */
def ifTest (i: I) : O = i.map (CaseTernIf.aORbIf)
def caseTest (i: I) : O = i.map (CaseTernIf.aORbCase)
def ternTest (i: I) : O = i.map (CaseTernIf.aORbTern)
// Map of Test names -> methods to test
val list2bench: List [(String, I => O)] = List (
"if test" -> ifTest _
, "case test" -> caseTest _
, "tern test" -> ternTest _
)
def test = {
list2bench.foreach (algo => println (algo._2))
}
}
And here is the BenchCoat source
Ternary operator is most efficient simply because it doesn't require "goto"'s in the assembly where else-if blocks do. I think switch cases are no more efficient than else-if blocks, assuming all you're doing in the else-if blocks is comparing one value to another (since essentially that's all switch is doing ultimately).
However, you should factor in another consideration: clarity. More important picking the usage which is most efficient is writing clear and concise code. For this, I would recommend else-if or switch blocks rather than ternary operators since you begin to cross eyes looking for the value that gets returned otherwise.
There isn't much difference if you are using a modern compiler. After compiler optimizes the code, native code should be almost the same.
The ternary operator is just a shorthand form of writing an if (something) { yay } else { boo }, with an easier assignment performed. The ternary operator will expand to an if else construct, there is no difference in bytecode.
I did the following test:
public class IfElseSwichTernary {
public static int aORbIf(int a) {
int x = 0;
if (a == 2) {
x = 4;
} else if (a == 3) {
x = 5;
} else if (a == 4) {
x = 6;
} else {
x = 7;
}
return x;
}
public static int aORbTern(int a) {
int x = 0;
x = (a == 2) ? 4 : ((a == 3) ? 5 : ((a == 4) ? 6 : 7));
return x;
}
public static int aORbCase(int a) {
int x = 0;
switch (a) {
case 2:
x = 4;
break;
case 3:
x = 5;
break;
case 4:
x = 6;
break;
default:
x = 7;
}
return x;
}
}
And I decompied with a java decompiler and got the following code:
public class IfElseSwichTernary {
public static int aORbIf(int a) {
int x = 0;
if (a == 2) {
x = 4;
} else if (a == 3) {
x = 5;
} else if (a == 4) {
x = 6;
} else {
x = 7;
}
return x;
}
public static int aORbTern(int a) {
int x = 0;
x = (a == 2) ? 4 : ((a == 3) ? 5 : ((a == 4) ? 6 : 7));
return x;
}
public static int aORbCase(int a) {
int x = 0;
switch (a) {
case 2:
x = 4;
break;
case 3:
x = 5;
break;
case 4:
x = 6;
break;
default:
x = 7;
}
return x;
}
}
Which means that the compiler doesn't change anything (I don't know if the JVM will change when converting it and running the insructions)
If it says in the same logic than Switch is more to the perfomace when we are talking more than two conditions.
It depends on the implementation of the JVM and also the version, you can't say in general, if a statement is the fastest.
for example the bytecode generated could also be the same for all statements.