Performance: greater / smaller than vs not equal to

前端 未结 7 1549
礼貌的吻别
礼貌的吻别 2020-12-14 14:47

I wonder if there is a difference in performance between

checking if a value is greater / smaller than another

for(int x = 0; x <         


        
相关标签:
7条回答
  • 2020-12-14 15:14

    Other people seem to have answered from a measured perspective, but from the machine level you'd be interested in the Arithmetic Logic Unit (ALU), which handles the mathy bits on a "normal computer". There seems to be a pretty good detail in How does less than and greater than work on a logical level in binary? for complete details.

    From purely a logical level, the short answer is that it's easier to tell if something is not something than it is to tell if something is relative to something, however this has likely been optimized in your standard personal computer or server, so you'll only see actual gains likely in small personal builds like on-board computers for drones or other micro-technologies.

    0 讨论(0)
  • 2020-12-14 15:14

    Now 6 years later and after still receiving occasional notifications from this question I'd like to add some insights that I've gained during my computer science study.

    Putting the above statements into a small program and compiling it...

    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
            }
        }
    }
    

    ... we get the following bytecode:

      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
    

    As we can see, on bytecode level both are handled in the same way and use a single bytecode instruction for the comparison.

    As already stated, how the bytecode is translated into assembler/machine code depends on the JVM. But generally this conditional jumps can be translated to some assembly code like this:

    ; 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
    

    On hardware level JGE and JE have the same complexity.

    So all in all: Regarding performance, both x < y and x != y are theoretically the same on hardware level and one isn't per se faster or slower than the other.

    0 讨论(0)
  • 2020-12-14 15:18

    The performance is absolutely negligible. Here's some code to prove it:

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

    The results:

    Test One: 342
    Test Two: 332
    Test One: 340
    Test Two: 340
    Test One: 415
    Test Two: 325
    Test One: 393
    Test Two: 329
    
    0 讨论(0)
  • 2020-12-14 15:24

    There is rarely a performance hit but the first is much more reliable as it will handle both of the extraordinary cases where

    1. y < 0 to start
    2. x or y are messed with inside the block.
    0 讨论(0)
  • 2020-12-14 15:27

    You should still do what is clearer, safer and easier to understand. These micro-tuning discussions are usually a waste of your time because

    • they rarely make a measurable difference
    • when they make a difference this can change if you use a different JVM, or processor. i.e. without warning.

    Note: the machine generated can also change with processor or JVM, so looking this is not very helpful in most cases, even if you are very familiar with assembly code.

    What is much, much more important is the maintainability of the software.

    0 讨论(0)
  • 2020-12-14 15:29

    Wonder if nested for each test, same results ?

    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++) {}    
    }
    
    0 讨论(0)
提交回复
热议问题