Performance 哪种情况在技术上更有效,i>;=0或i>-1.

Performance 哪种情况在技术上更有效,i>;=0或i>-1.,performance,comparison,cpu-usage,conditional-statements,Performance,Comparison,Cpu Usage,Conditional Statements,这种用法在编写循环时很常见 我想知道I>=0是否需要更多的CPU周期,因为与I>-1相比,它有两个条件大于或等于。一个比另一个好,如果是,为什么?这是不正确的。JIT将把这两个测试作为一条机器语言指令来实现 CPU时钟周期的数量不是由比较到零或-1的数量决定的,因为CPU应该进行一次比较,并设置标志来指示比较的结果是或= 这些指令中的一条可能在某些处理器上更有效,但这种微优化几乎总是不值得做的。(JIT或javac也有可能为两个测试实际生成相同的指令。)相反,带零的比较(包括非严格比较)减少一条

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


我想知道
I>=0
是否需要更多的CPU周期,因为与
I>-1
相比,它有两个条件
大于或等于
。一个比另一个好,如果是,为什么?这是不正确的。JIT将把这两个测试作为一条机器语言指令来实现

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


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

相反,带零的比较(包括非严格比较)减少一条CPU指令。x86体系结构支持在任何算术或加载操作之后进行条件跳转。它反映在Java字节码指令集中,有一组指令用于比较堆栈顶部的值并跳转:
ifeq
/
ifgt
/
ifge
/
iflt
/
ifle
/
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;
}
第二个版本长一个字节:

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 
在我的机器上它的性能稍微好一点(让我吃惊的是,我希望JIT能将这些循环编译成相同的程序集。)

С结论
在合理的情况下与零进行比较。

我建议你永远不会注意到区别,所以做些可读性更好的事情。@SaadAbdullah你为什么这么认为?@SaadAbdullah正数到负数的转换?想得太多了。Java在内部处理这个问题。两种形式的表现应该相同。这真的是一个4票赞成的问题吗?这个问题不是基于意见的@萨达杜拉是对的。从性能角度来看,使用0进行比较通常更可取,因为与非零比较相比,它们通常可以保存一条x86指令,因为
ZF
CF
,etc标志设置在每个算术或加载指令之后。@ElliottFrisch您是指Oracle javac吗?(Eclipse和GCC都有自己的Java编译器。)哪个版本?你测试过了吗?
Benchmark                   Mode Thr     Mean   Mean error    Units
t.LoopCond.loopM1Cond       avgt   1    0,319        0,004  usec/op
t.LoopCond.loopZeroCond     avgt   1    0,302        0,004  usec/op