Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/371.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 在循环中使用if语句的最佳方式是什么?_Java_Optimization_If Statement - Fatal编程技术网

Java 在循环中使用if语句的最佳方式是什么?

Java 在循环中使用if语句的最佳方式是什么?,java,optimization,if-statement,Java,Optimization,If Statement,我有一张清单需要处理。这些项目要么已启用,要么已禁用。用户可以选择是否显示禁用的项目 因此,您有依赖于项目的cond2,而没有依赖于项目的cond1。我陷入了两难境地:我应该使用cond1&&!cond2或!(!cond1 | | cond2)?或者我应该在循环之前检查cond2(显示禁用项)?我还想(正如你在我所写的代码中看到的那样)我是否应该把cond2放在cond1之前,因为cond2 是一个布尔变量,使用“短路”(惰性计算?)会更快吗 我主要关心的是速度。如果循环中有许多项,这可能是一个

我有一张清单需要处理。这些项目要么已启用,要么已禁用。用户可以选择是否显示禁用的项目

因此,您有依赖于项目的
cond2
,而没有依赖于项目的
cond1
。我陷入了两难境地:我应该使用
cond1&&!cond2
!(!cond1 | | cond2)
?或者我应该在循环之前检查
cond2
(显示禁用项)?我还想(正如你在我所写的代码中看到的那样)我是否应该把
cond2
放在
cond1
之前,因为
cond2
是一个布尔变量,使用“短路”(惰性计算?)会更快吗

我主要关心的是速度。如果循环中有许多项,这可能是一个重要的更改

这是说明选项的代码:

// First Option
for (String item : items) {
    doSomethingFirst(item);
    if (isDisabled(item) && !showDisabled) {
        continue;
    }
    doSomethingElse(item);
}

// Second Option
for (String item : items) {
    doSomethingFirst(item);
    if (!(!isDisabled(item) || showDisabled)) {
        continue;
    }
    doSomethingElse(item);
}

// Third Option
if (showDisabled) {
    for (String item : items) {
        doSomethingFirst(item);
        doSomethingElse(item);
    }
} else {
    for (String item : items) {
        doSomethingFirst(item);
        if (isDisabled(item)) {
            continue;
        }
        doSomethingElse(item);
    }
}
那么,
isDisabled(item)
showdabled
的顺序是否重要?我应该在循环之前检查一下吗?还是编译器优化了它?(我怀疑……)

PS我不知道如何进行测量以查看实际值,如果相关,请进行测量


谢谢。

对于这些类型的问题,您应该衡量这一点,以确定这本身是否是您的瓶颈。如果是的话,那么我会衡量替代方案。我怀疑在上述情况下,它几乎不会对您的备选方案产生任何影响,特别是因为您可能会对列表项进行更为重要的操作(显示它们?将它们写入数据库或文件?)


衡量这一点的最简单方法是生成一个相当大的列表,在处理之前记录时间(例如,通过System.currentTimeMillis()),然后记录所用的毫秒(或秒)

在Java中,表达式从左到右求值。如果第一个条件为假,则不执行第二个条件;如果第一个条件为真,则不执行第二个条件

因此,在您的情况下,请尝试将可以更快解决的条件放在首位
showdabled

对于第三个例子,它看起来更好,因为您只检查了一次布尔值,但我想它不会真正改变性能,布尔值比较并不是非常昂贵。在代码的其他部分,您可能会有更好的改进。(就可读性而言,这不是我最喜欢的——相当长)

如果您想测量您案例中的性能,请使用探查器

或添加您的代码:

long start=System.currentTimeMillis();
//code to analyse
long timeSpent = System.currentTimeMillis()-start
您必须将代码放入一个循环中,以使其具有相关性。您可能会注意到,经过一些循环之后,Java将提高性能;)

我应该使用cond1&!康多尔!(!cond1 | | cond2)?或者我应该在循环之前检查cond2(显示禁用项)

最能表达你思想的东西,即更具可读性的东西

我主要关心的是速度

写作速度?重构速度?编译速度?发展速度?阅读和理解速度?调试速度?执行速度


你不可能一次拥有全部。没有语言。

我将选择选项1,只需反转开关

isDisabled(item) && !showDisabled

如果
isDisabled(…)
和您说的一样慢,那么最好先测试更快的情况。 现在,与其他选项相比,这是最明确和可读的:

  • 我们为所有项目都做了一些事情
  • 我们跳过验证某些测试的项目
  • 我们为所有其他项目做一些事情

很难做到更明确。第三个选项非常难看。

关于可读性,另一个好的做法是将函数和变量命名为正状态。双重否定很难理解。你喜欢读哪一本

enabled

虽然在一些情况下,以否定的形式命名事物是有意义的。例如,如果您将它们用于终止条件,例如文件结束<代码>而(!feof(fp))

但在大多数情况下,规范应该是以积极的形式命名,因此阅读代码的摩擦较小

让我们看看您的代码是如何以正数形式显示的:

// First Option
for (String item : items) {
    doSomethingFirst(item);

    // if (isDisabled(item) && !showDisabled) {

    if (!isEnabled(item) && showEnabled) {
        continue;
    }
    doSomethingElse(item);
}
该代码的可读性肯定有所提高

即使下面的内容也变得可读,双重否定是可以避免的,阅读代码实际上只是阅读它,而不是过多地理解它。我曾经读过一篇文章,其中建议在编写代码时,阅读也应该非常愉快,他说阅读代码不应该像阅读侦探小说一样。阅读双重否定密码就像阅读和破译侦探小说

// Second Option
for (String item : items) {
    doSomethingFirst(item);

    // if (!(!isDisabled(item) || showDisabled)) {

    // You can now avoid double negatives
    if (!( isEnabled(item) || !showEnabled )) {
        continue;
    }
    doSomethingElse(item);
}
事实上,以下不仅仅是双重否定,而是三重否定:

如果(!(!isDisabled(项目)

  • 禁用
  • !已禁用
  • !(!已禁用

  • 需要两次读取,甚至三次读取才能破译该代码的意图

    所以你是说选项1和2是相似的,只要先计算常数?从意义上看是一样的,但从速度上看也是一样的?是的,在这种情况下是一样的,但第二个选项读起来很糟糕;)如果if语句中没有对性能产生影响的大量方法调用,请选择可读性最好的方法。实际上,我担心
    isDisabled
    可能会很慢…这就是条件本身…我将尝试进行测量。这不重要。选择可读性最好的方法。@delnan我会想到第三个选项更快,不是吗?但我会重复我自己。所以可读性--;如果你做了一个微基准测试,它可能会更快。它也可能会更慢-例如,由于CPU缓存,JVM优化可能会优化一个循环,但忽略了另一个,内联可能会因为代码膨胀而被阻止-所以我拒绝猜测。但是,我99%确信任何差异都会太大购物中心为你花在思考和做这件事上的时间(n
    // First Option
    for (String item : items) {
        doSomethingFirst(item);
    
        // if (isDisabled(item) && !showDisabled) {
    
        if (!isEnabled(item) && showEnabled) {
            continue;
        }
        doSomethingElse(item);
    }
    
    // Second Option
    for (String item : items) {
        doSomethingFirst(item);
    
        // if (!(!isDisabled(item) || showDisabled)) {
    
        // You can now avoid double negatives
        if (!( isEnabled(item) || !showEnabled )) {
            continue;
        }
        doSomethingElse(item);
    }