哪种条件在技术上更有效,i> = 0或i> 1。 -1?

时间:2013-11-13 06:27:10

标签: performance comparison cpu-usage conditional-statements

这种用法在编写循环时很常见。

我想知道i >=0是否需要更多的CPU周期,因为它与greater than OR equal to相比有两个条件i > -1。是否已知一个比另一个好,如果是,为什么?

2 个答案:

答案 0 :(得分:7)

这不正确。 JIT将两个测试都作为单一机器语言指令实现。

CPU时钟周期数不是由零或-1的比较数决定的,因为CPU应进行一次比较并设置标志以指示比较结果是否为<,>。或=。

这些指令之一可能在某些处理器上更有效,但这种微优化几乎总是不值得做。 (也有可能JIT - 或者javac - 实际上会为两个测试生成相同的指令。)

答案 1 :(得分:3)

相反,带零的比较(包括非严格)会减少一条CPU指令。 x86架构支持任何算术或加载操作后的条件跳转。它反映在Java字节码指令集中,有一组指令用于比较堆栈顶部的值和跳转:ifeq / ifgt / ifge / {{1} } / iflt / ifle。 (见the full list)。与ifne的比较需要额外的-1操作(将iconst_m1常量加载到堆栈上)。

有两个不同比较的循环:

-1

第二个版本长一个字节:

@GenerateMicroBenchmark
public int loopZeroCond() {
    int s = 0;
    for (int i = 1000; i >= 0; i--) {
        s += i;
    }
    return s;
}

@GenerateMicroBenchmark
public int loopM1Cond() {
    int s = 0;
    for (int i = 1000; i > -1; i--) {
        s += i;
    }
    return s;
}

我的机器性能略高一些(令我惊讶的是。我希望JIT将这些循环编译成相同的程序集。)

public int loopZeroCond();
  Code:
     0: iconst_0      
     1: istore_1      
     2: sipush        1000
     5: istore_2      
     6: iload_2       
     7: iflt          20               //
    10: iload_1       
    11: iload_2       
    12: iadd          
    13: istore_1      
    14: iinc          2, -1
    17: goto          6
    20: iload_1       
    21: ireturn       

public int loopM1Cond();
  Code:
     0: iconst_0      
     1: istore_1      
     2: sipush        1000
     5: istore_2      
     6: iload_2       
     7: iconst_m1                   //
     8: if_icmple     21            //
    11: iload_1       
    12: iload_2       
    13: iadd          
    14: istore_1      
    15: iinc          2, -1
    18: goto          6
    21: iload_1       
    22: ireturn 

Сonclusion

每当明智时,

与零比较。