Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
以下哪一项在java中最有效?_Java_Performance_Conditional Statements - Fatal编程技术网

以下哪一项在java中最有效?

以下哪一项在java中最有效?,java,performance,conditional-statements,Java,Performance,Conditional Statements,可能重复: 对于编程中观察到的所有条件语句,以下哪一个块是最首选的: 三元运算符 else if块 开关块 提前谢谢 三元运算符是最有效的,因为它不需要程序集中的“goto”,如果块需要的话。我认为switch情况并不比elseif块更有效,假设你在elseif块中所做的一切都是比较一个值和另一个值(因为本质上这就是switch最终所做的一切) 但是,您应该考虑另一个因素:清晰度。更重要的是,选择最有效的用法是编写清晰简洁的代码。为此,我建议使用else-if或switch块,而不是三元运算符

可能重复:

对于编程中观察到的所有条件语句,以下哪一个块是最首选的:

  • 三元运算符
  • else if块
  • 开关块

  • 提前谢谢

    三元运算符是最有效的,因为它不需要程序集中的“goto”,如果块需要的话。我认为switch情况并不比elseif块更有效,假设你在elseif块中所做的一切都是比较一个值和另一个值(因为本质上这就是switch最终所做的一切)


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

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

    三元运算符只是编写if(something){yay}else{boo}的一种简写形式,执行赋值更容易。三元运算符将扩展为if-else结构,字节码没有差异。

    当然,您可以用不同的方式实现比较

    我是这样做的:

    公共块:

    int a = 42;
    int k = 17;
    
    如果:

    if (a == 42) 
        k+=4;
    else    k+=5;
    
    案例:

    switch (a) {
        case 42: k+=4; break;
        default: k+=5; break;
    }
    
    三元:

    k += (a == 42) ? 4 : 5; 
    
    它们不会编译为相同的字节码:

    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
    
    然而,当您有多种情况时,而不仅仅是两种情况时,switch的优势就会发挥作用

    If和三元逻辑在超过2种情况下得到级联

    但它们在习惯用法/语义上有所不同。三值运算符返回某些内容,但不返回if或开关

    所以,你要比较什么并不清楚

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

    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    
    

    这表明,它们确实没有多大区别,缓存效果仍然会对500万个案例产生影响,即使在对VM进行加热之后也是如此

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

    以下是我测试的代码:

    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; 
            }
        }
    }
    
    以下是测试代码(即Scala):

    对象ifcaseterbench扩展Benchcoat[List[Int],Seq[Int]]{
    类型I=列表[Int]
    类型O=序号[Int]
    val name=“caseern”
    /**我们在这里返回一个随机整数列表*/
    def iGenerator(n:Int):I=(用于(x个要测试的方法
    val list2bench:List[(字符串,I=>O)]=List(
    “如果测试”->ifTest_
    ,“案例测试”->案例测试_
    ,“tern测试”->tern测试_
    )
    def test={
    list2bench.foreach(算法=>println(算法2))
    }
    }
    
    更新:
    这是我做的以下测试:

    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;
        }
    }
    
    我用java反编译器进行了反编译,得到了以下代码:

    公共类ifelseswich{

    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;
    }
    
    }

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


    当我们讨论两个以上的条件时,如果它以相同的逻辑表示,那么Switch更符合性能。

    这取决于JVM的实现以及版本,一般来说,你不能说一个语句是否最快


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

    为什么不对其进行基准测试,并找出原因?是否存在性能问题?过早优化,因为其中大多数可能会导致相同的字节码!之前在stackoverflow检查时曾询问过这不是一个同源工作问题,否则我会问已将其标记为家庭作业。谢谢@ChristopheDHe,他只是在性能方面提问。因此,这并不能回答问题。您是否通过查看三元组生成的字节码来检查此问题?@JohnDoe,我回答了他的问题,并添加了更相关的信息。检查哪一个测试了此问题。当您在上面的条件块排列程序中不要使用goto,所以所有关于它被编译成相同字节码的说法都是不正确的?@AnuragRamdasan:我认为是这样。因为代码大小不同。但是可能另一个要精确比较的实现,或者不同的编译器,或者HotSpotCompiler最终对代码所做的事情会改变图片e、 @Neil:是的,谢谢,我更新了表格。在我对代码做了或多或少的修饰性修改后,我进行了第二次运行,以确保结果不会发生显著变化。在更新图表后,我忘记了更新表格。现在完成了。@Neil:是的,但不应该发生这种情况。我手动更正了它,但我必须调查其来源关于这个错误。我有一个简短的问题。你到底是如何进行基准测试的?我从来没有这样做过,我想我会在完成我的应用程序原型后立即使用它。只要一个链接就好了。我真的很感激!请不要传播三元运算符是一个缩写if语句的神话。你的开关/案例缺少
    break;
    语句,并且失败了。
    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;
    }