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

btqmn9zl  于 2021-07-09  发布在  Java
关注(0)|答案(9)|浏览(499)

假设我有一个 IF 条件:

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

现在假设 A 更可能得到一个真实的值 B ,为什么我要在意左边是哪一个?
如果我把它们都放在 IF 括号,然后我知道(作为代码的程序员)双方都是需要的。
问题是,我的教授在他的讲稿上写道,我应该把“更可能得到真值的变量”放在左边。
有人能解释一下好处吗?好的,我把它放在左边。。。我得到了什么?运行时间?

pkmbmrz7

pkmbmrz71#

在运行时,如果(a | | b)将首先测试a,如果a为真,则不会浪费时间测试b,因此编译器将提前1次执行。因此,如果a比b更可能是真的,那么这个测试也可能切1条线。在一行中未执行的行的总数很小,但是如果语句嵌套在某种循环中(例如,while或与数据库相关的查询),则会非常大。例如,假设我们有100万分钟的时间来测试数据库中的数据,每个记录1分钟(条件a为30秒,条件b为30秒)。让a有80%的几率是真的,b有20%的几率是真的。如果你把a放在第一位所需的总时间是60-000小时,而把b放在第一位所需的总时间是90-000小时。如果a先测试[(0,8*1百万小时)0,5分钟+(0,21百万小时)*1分钟]==6000-000小时:如果b先测试[(0,2*1百万小时)0,5分钟+(0,21百万小时)*1分钟]==9000-000小时。然而,你会注意到,如果a变为真的概率更接近b,那么差异就不那么显著了。

t1rydlwq

t1rydlwq2#

在许多情况下,除了微小的性能改进之外,没有实际的区别。如果您的检查是非常昂贵的函数调用(不太可能),或者您需要按顺序检查,那么这将非常有用。例如,如果要检查某个对象的属性并首先检查该对象是否为零,可以执行以下操作:
如果(a!=nil&&a.attribute==有效){}

ncgqoxb0

ncgqoxb03#

是的,正是这样,你获得了运行时间,一个操作看起来不多,但你必须记住,操作会被重复数百万次
为什么要在一个评估足够的情况下执行两个评估

hfyxw5xn

hfyxw5xn4#

我把它放在左边。。。我得到了什么?运行时间?
因为 || c中的运算符使用短路求值。
即: B 仅当 A 被评估为 false .
但是,请注意,在c
中,短路评估是针对“内置”数据类型而不是自定义数据类型的。

xggvc2p6

xggvc2p65#

根据javadoc
&&和| |运算符对两个布尔表达式执行条件and和条件or运算。这些运算符表现出“短路”行为,这意味着只有在需要时才计算第二个操作数
因此,如果true语句按顺序排在第一位,它将在运行时短路第二个操作数。

muk1a3rh

muk1a3rh6#

您应该首先放置更可能为真的条件,因为这将导致if语句短路。这意味着它不会计算if语句的其余部分,因为它已经知道答案是真的。这使得代码更高效。
当您的if语句正在评估昂贵的东西时,这尤其有用:

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

在这种情况下,由于支票是昂贵的,它是在您的利益放在最有可能的检查第一。

jvidinwx

jvidinwx7#

这不仅仅是选择左边最可能的情况。你也可以在左边有一个安全警卫,这意味着你只能有一个订单。考虑

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

为什么选择最有可能是真的 || 或为假 && 是一个微观优化,以避免在第二个表达式中计算的成本。这是否转化为可测量的性能差异是有争议的。

ogsagwnx

ogsagwnx8#

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

你好,世界

68de4m5k

68de4m5k9#

如果左侧的表达式为true,则不需要计算右侧的表达式,因此可以在运行时对其进行优化。这是一种叫做短路的技术。因此,通过将表达式更可能为真的放在左边,我们可以期望我们的程序执行得更好。

相关问题