哪些是java中最有效的?

Anu*_*san 3 java performance conditional-statements

可能重复:
Java:If与Switch

对于在编程中观察到的所有条件语句,哪些块是最优选的:

  1. 三元运算符
  2. else-if阻止
  3. 开关块

提前致谢!

use*_*own 5

当然,您可以通过不同方式实施比较.

我是这样做的:

共同块:

int a = 42;
int k = 17;
Run Code Online (Sandbox Code Playgroud)

如果:

if (a == 42) 
    k+=4;
else    k+=5;
Run Code Online (Sandbox Code Playgroud)

案件:

switch (a) {
    case 42: k+=4; break;
    default: k+=5; break;
}
Run Code Online (Sandbox Code Playgroud)

三元:

k += (a == 42) ? 4 : 5; 
Run Code Online (Sandbox Code Playgroud)

它们不会编译为相同的字节码:

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
Run Code Online (Sandbox Code Playgroud)

但是,当您有多个案例时,开关的优势就会发挥作用 - 而不仅仅是2个案例.

如果和三元级联超过2个案例.

但它们在惯用/语义上有所区别.三元运算符返回一些东西,但不返回if或switch.

所以你不得不比较清楚.

但我做了一个基准,结果如下:

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    
Run Code Online (Sandbox Code Playgroud)

基准情节(基准图)

这表明,他们确实没有太大的区别,并且即使在加热VM之后,对于5 M的情况,缓存效果仍然存在影响.

在实际情况下,您很少有几百万次调用,几乎没有任何事情发生.但是如果发生了什么事情,if/case/ternary的时间很快变得无关紧要.

这是我测试的代码:

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; 
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是测试代码(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))
  }
}
Run Code Online (Sandbox Code Playgroud)

更新:

这是BenchCoat的来源

  • @Neil:是的,谢谢,我更新了表格.在我做了一个或多或少的化妆品代码更改后,我做了第二次运行,只是为了确保结果不会发生显着变化.更新图表后,我忘了更新表格.现在完成了. (2认同)
  • @Neil:是的,但这不应该发生.我手动纠正了它,但我必须调查此错误的来源. (2认同)