45

我想知道两者之间是否存在性能差异

检查一个值是否大于/小于另一个

for(int x = 0; x < y; x++); // for y > x

检查一个值是否不等于另一个

for(int x = 0; x != y; x++); // for y > x

为什么?

另外:如果我与零比较,是否还有进一步的区别?

如果答案也考虑对代码的组装视图,那就太好了。

编辑: 正如你们大多数人指出的那样,性能差异当然可以忽略不计,但我对 cpu 级别的差异感兴趣。哪个操作更复杂?

对我来说,学习/理解这项技术更多的是一个问题。

我删除了Java标签,这是我不小心添加的,因为这个问题通常不仅仅基于 Java,抱歉。

4

7 回答 7

38

你仍然应该做更清晰、更安全、更容易理解的事情。这些微调讨论通常是在浪费您的时间,因为

  • 他们很少会产生可衡量的差异
  • 当它们产生影响时,如果您使用不同的 JVM 或处理器,这可能会改变。即没有警告。

注意:生成的机器也会随着处理器或 JVM 的变化而变化,因此在大多数情况下,即使您非常熟悉汇编代码,查看这也不是很有帮助。

更重要的是软件的可维护性。

于 2013-09-03T15:47:47.153 回答
16

性能绝对可以忽略不计。这里有一些代码来证明它:

public class OpporatorPerformance {
    static long y = 300000000L;

    public static void main(String[] args) {
        System.out.println("Test One: " + testOne());
        System.out.println("Test Two: " + testTwo());
        System.out.println("Test One: " + testOne());
        System.out.println("Test Two: " + testTwo());
        System.out.println("Test One: " + testOne());
        System.out.println("Test Two: " + testTwo());
        System.out.println("Test One: " + testOne());
        System.out.println("Test Two: " + testTwo());

    }

    public static long testOne() {
        Date newDate = new Date();
        int z = 0;
        for(int x = 0; x < y; x++){ // for y > x
            z = x;
        }
        return new Date().getTime() - newDate.getTime();
    }

    public static long testTwo() {
        Date newDate = new Date();
        int z = 0;
        for(int x = 0; x != y; x++){ // for y > x
            z = x;
        }
        return new Date().getTime() - newDate.getTime();
    }

}

结果:

Test One: 342
Test Two: 332
Test One: 340
Test Two: 340
Test One: 415
Test Two: 325
Test One: 393
Test Two: 329
于 2013-09-03T15:54:52.440 回答
13

现在 6 年后,在仍然偶尔收到来自这个问题的通知之后,我想补充一些我在计算机科学研究期间获得的见解。

把上面的语句放到一个小程序中,然后编译...

public class Comp {
    public static void main(String[] args) {
        int y = 42;

        for(int x = 0; x < y; x++) {
            // stop if x >= y
        }

        for(int x = 0; x != y; x++) {
            // stop if x == y
        }
    }
}

...我们得到以下字节码:

  public static void main(java.lang.String[]);
    Code:
       // y = 42
       0: bipush        42  
       2: istore_1

       // first for-loop
       3: iconst_0
       4: istore_2
       5: iload_2
       6: iload_1
       7: if_icmpge     16      // jump out of loop if x => y
      10: iinc          2, 1
      13: goto          5

       // second for-loop
      16: iconst_0
      17: istore_2
      18: iload_2
      19: iload_1
      20: if_icmpeq     29      // jump out of loop if x == y
      23: iinc          2, 1
      26: goto          18

      29: return

正如我们所看到的,在字节码级别,两者都以相同的方式处理,并使用单个字节码指令进行比较。

如前所述,如何将字节码翻译成汇编程序/机器码取决于 JVM。但通常这种条件跳转可以翻译成一些汇编代码,如下所示:

; condition of first loop
CMP eax, ebx
JGE label  ; jump if eax > ebx

; condition of second loop
CMP eax, ebx
JE  label  ; jump if eax == ebx

在硬件级别上,JGE 和 JE 具有相同的复杂性。

总而言之:关于性能,两者在硬件级别x < yx != y理论上是相同的,并且一个本身并不比另一个更快或更慢。

于 2019-09-13T16:08:26.190 回答
5

很少有性能影响,但第一个更可靠,因为它可以处理两种特殊情况

  1. y < 0 开始
  2. x 或 y 在块内被弄乱了。
于 2013-09-03T15:45:41.893 回答
3

理论上的表现是一样的。当您执行小于或不等于运算时,在处理器级别您实际上执行减法运算并检查结果中是否启用了负标志或零标志。理论上性能是一样的。因为区别只是检查标志集。

于 2019-12-12T07:08:34.153 回答
2

其他人似乎从测量的角度回答了问题,但从机器级别来看,您会对算术逻辑单元 (ALU) 感兴趣,它处理“普通计算机”上的数学位。似乎有一个很好的细节,小于和大于如何在二进制逻辑级别上工作?有关完整的详细信息。

从纯粹的逻辑层面来看,简短的回答是,判断某物是否不是某物比判断某物是否与某物相关更容易,但是这可能已在您的标准个人计算机或服务器中进行了优化,因此您将仅在小型个人构建(例如无人机或其他微技术的机载计算机)中看到实际收益。

于 2019-02-13T20:37:48.217 回答
-5

想知道每个测试是否嵌套,结果相同?

for(int x = 0; x < y; x++)
{   
  for(int x2 = 0; x2 < y; x2++)  {}   
}

for(int x = 0; x != y; x++)
{
  for(int x2 = 0; x2 != y; x2++) {}    
}
于 2015-09-11T18:57:30.487 回答