哪些是java中最有效的? [重复]

时间:2022-09-23 17:17:55

Possible Duplicate:
Java: If vs. Switch

可能重复:Java:If与Switch

For all the conditional statements that are observed in programming, which of these blocks is the most preferred:

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

  1. Ternary operator
  2. 三元运算符
  3. else-if block
  4. else-if块
  5. switch block
  6. 开关块

Thanks in advance!

提前致谢!

7 个解决方案

#1


5  

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.

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

If and ternary get cascading for more than 2 cases.

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

But they differ idiomatically/semantically. The Ternary operator returns something, but not the if or the switch.

但它们在惯用/语义上有所区别。三元运算符返回一些东西,但不返回if或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    

哪些是java中最有效的? [重复]

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.

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

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.

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

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):

这是测试代码(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))
  }
}

updated:

And here is the BenchCoat source

这是BenchCoat的来源

#2


1  

There isn't much difference if you are using a modern compiler. After compiler optimizes the code, native code should be almost the same.

如果您使用的是现代编译器,则没有太大区别。在编译器优化代码之后,本机代码应该几乎相同。

#3


1  

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).

三元运算符是最有效的,因为它不需要在其他if-if块的汇编中使用“goto”。我认为切换案例并不比else-if块更有效,假设你在else-if块中所做的只是将一个值与另一个值进行比较(因为基本上所有交换机最终都在做)。

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.

但是,您应该考虑另一个因素:清晰度。更重要的是选择最有效的用法是编写清晰简洁的代码。为此,我建议使用else-if或切换块而不是三元运算符,因为你开始越过眼睛寻找返回的值否则返回。

#4


0  

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.

三元运算符只是编写if(某事物){yay} else {boo}的简写形式,执行更简单的赋值。三元运算符将扩展为if else构造,字节码没有区别。

#5


0  

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:

我用java反编译器解压缩并得到以下代码:

public class IfElseSwichTernary {

公共课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)

这意味着编译器不会改变任何东西(我不知道JVM在转换它并运行insructions时是否会改变)

If it says in the same logic than Switch is more to the perfomace when we are talking more than two conditions.

如果它说的是相同的逻辑,那么当我们谈论两个以上的条件时,Switch更多的是性能。

#6


0  

It depends on the implementation of the JVM and also the version, you can't say in general, if a statement is the fastest.

它取决于JVM的实现以及版本,一般来说,如果语句是最快的,则不能说。

for example the bytecode generated could also be the same for all statements.

例如,生成的字节码对于所有语句也可以是相同的。

#7


-2  

You have three conditional block arrangers:

您有三个条件块排列器:

  1. Ternary operator
  2. 三元运算符
  3. else-if block
  4. else-if块
  5. switch case
  6. 开关盒

They all perform the same in case of performnce but ironically they are turned to the same code when they are compiled to byte-code by the compiler

它们在执行时都执行相同的操作,但具有讽刺意味的是,当它们被编译器编译为字节代码时,它们被转换为相同的代码

#1


5  

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.

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

If and ternary get cascading for more than 2 cases.

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

But they differ idiomatically/semantically. The Ternary operator returns something, but not the if or the switch.

但它们在惯用/语义上有所区别。三元运算符返回一些东西,但不返回if或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    

哪些是java中最有效的? [重复]

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.

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

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.

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

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):

这是测试代码(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))
  }
}

updated:

And here is the BenchCoat source

这是BenchCoat的来源

#2


1  

There isn't much difference if you are using a modern compiler. After compiler optimizes the code, native code should be almost the same.

如果您使用的是现代编译器,则没有太大区别。在编译器优化代码之后,本机代码应该几乎相同。

#3


1  

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).

三元运算符是最有效的,因为它不需要在其他if-if块的汇编中使用“goto”。我认为切换案例并不比else-if块更有效,假设你在else-if块中所做的只是将一个值与另一个值进行比较(因为基本上所有交换机最终都在做)。

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.

但是,您应该考虑另一个因素:清晰度。更重要的是选择最有效的用法是编写清晰简洁的代码。为此,我建议使用else-if或切换块而不是三元运算符,因为你开始越过眼睛寻找返回的值否则返回。

#4


0  

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.

三元运算符只是编写if(某事物){yay} else {boo}的简写形式,执行更简单的赋值。三元运算符将扩展为if else构造,字节码没有区别。

#5


0  

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:

我用java反编译器解压缩并得到以下代码:

public class IfElseSwichTernary {

公共课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)

这意味着编译器不会改变任何东西(我不知道JVM在转换它并运行insructions时是否会改变)

If it says in the same logic than Switch is more to the perfomace when we are talking more than two conditions.

如果它说的是相同的逻辑,那么当我们谈论两个以上的条件时,Switch更多的是性能。

#6


0  

It depends on the implementation of the JVM and also the version, you can't say in general, if a statement is the fastest.

它取决于JVM的实现以及版本,一般来说,如果语句是最快的,则不能说。

for example the bytecode generated could also be the same for all statements.

例如,生成的字节码对于所有语句也可以是相同的。

#7


-2  

You have three conditional block arrangers:

您有三个条件块排列器:

  1. Ternary operator
  2. 三元运算符
  3. else-if block
  4. else-if块
  5. switch case
  6. 开关盒

They all perform the same in case of performnce but ironically they are turned to the same code when they are compiled to byte-code by the compiler

它们在执行时都执行相同的操作,但具有讽刺意味的是,当它们被编译器编译为字节代码时,它们被转换为相同的代码