Cycle counter in Java API

All,

When viewing some files in the Java API, I noticed many cases where the loop counter is decreasing rather than increasing. those. in loops forand whilein class String . Although this may be trivial, is there any value for decreasing the counter, not increasing it?

+3
source share
3 answers

I put together two simple loops with eclipse 3.6 (java 6) and looked at the byte code to see if we have some differences. Here is the code:

for(int i = 2; i >= 0; i--){}
for(int i = 0; i <= 2; i++){}

And this is the bytecode:

// 1st for loop - decrement 2 -> 0
 0 iconst_2
 1 istore_1      // i:=2
 2 goto 8
 5 inc 1 -1      // i+=(-1)
 8 iload_1
 9 ifge 5        // if (i >= 0) goto 5

// 2nd for loop - increment 0 -> 2
12 iconst_0 
13 istore_1      // i:=0
14 goto 20
17 inc 1 1       // i+=1
20 iload_1
21 iconst 2
22 if_icmple 17  // if (i <= 2) goto 17

increment/decment , +1, +(-1). (!) , 0 (ifge i), (if_icmple i 2). . , - () , , 0, . , /, , .

, - , , , ( - ):

 for (int i =  0; i <= 2; i++) {}  // readable
 for (int i = -2; i <= 0; i++) {}  // micro-optimized and "faster" (hopefully)

- 2000x2000 , 0->1999 , 1999->0. , (185..210 ).

, , (eclipse 3.6), , , 2010 , , . , , , " " ​​. .

+7

, .

public class IncDecTest
{
    public static void main(String[] av)
    {
        long up = 0;
        long down = 0;
        long upStart, upStop;
        long downStart, downStop;
        long upStart2, upStop2;
        long downStart2, downStop2;

        upStart = System.currentTimeMillis();
        for( long i = 0; i < 100000000; i++ )
        {
            up++;
        }
        upStop = System.currentTimeMillis();

        downStart = System.currentTimeMillis();
        for( long j = 100000000; j > 0; j-- )
        {
            down++;
        }
        downStop = System.currentTimeMillis();

        upStart2 = System.currentTimeMillis();
        for( long k = 0; k < 100000000; k++ )
        {
            up++;
        }
        upStop2 = System.currentTimeMillis();

        downStart2 = System.currentTimeMillis();
        for( long l = 100000000; l > 0; l-- )
        {
            down++;
        }
        downStop2 = System.currentTimeMillis();

        assert (up == down);

        System.out.println( "Up: " + (upStop - upStart));
        System.out.println( "Down: " + (downStop - downStart));     
        System.out.println( "Up2: " + (upStop2 - upStart2));
        System.out.println( "Down2: " + (downStop2 - downStart2));
    }
}

JVM:

java version "1.6.0_22"
Java(TM) SE Runtime Environment (build 1.6.0_22-b04-307-10M3261)
Java HotSpot(TM) 64-Bit Server VM (build 17.1-b03-307, mixed mode)

( , , JVM , ).

$ java -ea IncDecTest
Up: 86
Down: 84
Up2: 83
Down2: 84

, , JVM, , , , .

- ( Java), , - voodoo, , .

/ , .

+2

, , Sun -, , , . , , Sun "", JIT... / /-.

, :

  • , ,
  • , ,
  • , JVM, .

, JVM , :

  • ,
  • the decrement cycle is really faster than the increment cycle for your particular application.

And even then, you may find that your carefully crafted code is less optimal on other platforms ... and you need to repeat the process again.

Nowadays, it is widely recognized that the best first strategy is to write simple code and leave the optimization to the JIT compiler. Writing complex code (for example, loops that execute in reverse order) can actually make it difficult to optimize the JIT compiler.

+2
source

Source: https://habr.com/ru/post/1774885/


All Articles