为什么if语句中的表达式顺序很重要

时间:2012-08-25 04:49:05

标签: java c++ c if-statement

假设我有一个IF条件:

if (A || B) 
    ∧
    |
    |
   left
{ 
   // do something  
}

现在假设A更有可能获得真值B,为什么我关心哪一个在左边?

如果我将它们都放在IF括号中,那么我知道(作为代码的程序员)需要双方。

问题是,我的教授在他的讲座上写道,我应该在左边写下“更可能的变量来接收真实”。

有人可以解释一下这个好处吗?好吧,我把它放在左边......我得到了什么?运行 ?

9 个答案:

答案 0 :(得分:21)

它不仅仅是选择左边最可能的条件。你也可以在左边有一个安全防护装置,这意味着你只能有一个订单。考虑

if (s == null || s.length() == 0) // if the String is null or empty.

你不能在这里交换订单,因为第一个条件是保护第二个投掷NPE。

同样可以

if (s != null && s.length() > 0) // if the String is not empty

||选择最可能为真的原因或为&&选择假的原因是微优化,以避免在第二个表达式中评估的成本。这是否会转化为可衡量的绩效差异值得商榷。

答案 1 :(得分:9)

  

我把它放在左边......我获得了什么?运行时间

因为C ++中的||运算符使用 short-circuit evaluation
 即:B仅在A评估为false时才会被评估。

但请注意,在C ++中,“内置”数据类型而不是自定义数据类型可以保证短路评估。

答案 2 :(得分:3)

根据javadoc

  

&&和||运算符对两个布尔表达式执行条件AND和条件OR运算。这些运算符表现出“短路”行为,这意味着仅在需要时才评估第二个操作数

因此,如果true语句在顺序中排在第一位,它会在运行时将第二个操作数短路。

答案 3 :(得分:2)

如果左边的表达式为true,则无需在右侧评估表达式,因此可以在运行时对其进行优化。这是一种称为短路的技术。因此,通过在左侧放置表达式更可能是真的,我们可以期望我们的程序比其他方式表现更好。

答案 4 :(得分:2)

您应该首先放置更可能为真的条件,因为这会导致if语句短路。这意味着它不会评估if语句的其余部分,因为它已经知道答案是真的。这使代码更有效。

当你的if语句评估昂贵的东西时,这个特别有用:

if(doExpensiveCheck1() || doExpensiveCheck2()) { }

在这种情况下,由于检查费用昂贵,最有可能首先进行检查。

答案 5 :(得分:2)

在许多情况下,除了微小的性能改进之外没有实际差异。如果您的检查是非常昂贵的函数调用(不太可能)或者您需要按顺序检查事物,那么这变得有用。比如说你想检查某个属性,并检查某些东西是否为零,你可以这样做:

如果(a!= nil&& a.attribute ==有效) {}

答案 6 :(得分:0)

确切地说,你正在获得运行时间,对于一个操作来说似乎没什么用,但你必须记住操作会重复数百万次

为什么在一个足够的时候进行两次评估是逻辑

答案 7 :(得分:0)

在运行时如果(a || b)将测试第一个,如果a为真,则不会浪费时间测试b因此编译器将提前1次执行。因此,如果a比b更可能是真的,那么这个测试也可能会减少1行。未执行的行总数在一行中很小,但如果语句嵌套在某种循环中(对于,同时,经济衰退或与数据库相关的查询),则会很大。例如,我们有100万分钟来测试数据库中每条记录1分钟的数据(条件A为30秒,条件B为30秒)。让A有80%的机会成真,B有20%的机会成真。如果你把A放在第一个是600-000小时所需的总时间,如果你把B放在第一位则需要900-000小时。如果首先测试A [(0,8 * 1百万小时)* 0.5分钟+(0,2 * 1百万小时) * 1分钟] === 6000-000小时:如果首先测试B [(0,2 * 1百万小时)* 0.5分钟+(0,2 * 1百万小时)* 1分钟] === 9000-000小时。但是,如果A变为真的概率接近于B的概率,则会注意到差异不太显着。

答案 8 :(得分:0)

public class Main
{
    public static void main(String[] args) {
        System.out.println("Hello World");
        Integer a = null;
        Integer b = 3;
        Integer c = 5;

        if(a != null && a == 2){
            System.out.println("both");
        }else{
            System.out.println("false");
        }
    }
}

Hello World