表现:大于/小于与不相等

das*_*eks 34 comparison performance jvm

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

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

for(int x = 0; x < y; x++); // for y > x
Run Code Online (Sandbox Code Playgroud)

检查某个值是否与另一个值不相等

for(int x = 0; x != y; x++); // for y > x
Run Code Online (Sandbox Code Playgroud)

为什么?

另外:如果我比较零怎么办?还有什么区别吗?

如果答案还考虑了代码上的分组视图,那将是很好的.

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

对我来说,学习/理解这项技术更具问题.

我删除了Java标签,我意外添加了标签,因为这个问题通常不仅仅基于Java,对不起.

Pet*_*rey 28

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

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

注意:生成的机器也可以随处理器或JVM一起更改,因此在大多数情况下,即使您非常熟悉汇编代码,查看这个也不是很有用.

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

  • 我不确定为什么这是投票最高的答案,因为 OP 提出了一个与性能相关的问题,而不是软件工程最佳实践。 (2认同)

Jam*_*unn 15

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

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

}
Run Code Online (Sandbox Code Playgroud)

结果:

Test One: 342
Test Two: 332
Test One: 340
Test Two: 340
Test One: 415
Test Two: 325
Test One: 393
Test Two: 329
Run Code Online (Sandbox Code Playgroud)

  • 您应该使用System.nanoTime()进行基准测试,这样可以提高精度. (6认同)

das*_*eks 7

现在 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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

  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
Run Code Online (Sandbox Code Playgroud)

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

如前所述,字节码如何转换为汇编程序/机器代码取决于 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
Run Code Online (Sandbox Code Playgroud)

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

所以,这一切的一切:关于性能,无论是x < yx != y理论上的硬件水平相同,一个是本身并不比其他的快或慢。


Old*_*eon 5

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

  1. y < 0 开始
  2. x 或 y 在块内被弄乱。