overexchange
overexchange

Reputation: 1

Why computation takes more time with long literal?

For a simple multithreaded code, as shown below,

It takes 41338 milliseconds to close the main thread, consistently with similar delay

if i replace long with an int, and compare like i < 0x7FFFFFFF it takes 28 milliseconds consistently with similar delay.

machine power: DELL E6430 latitude 64 bit machine running 64 bit JVM 1.6

public class Dummy {

    private static int NUM_OF_THREADS=200;

    private static Thread[] thread = null;

    public static void loopSomeTime(int i) {
        thread[i] = new Thread(new Runnable(){
            public void run(){
                int count = 0;
                for(long i = 0; i < 0x7FFFFFFFL; ++i){
                    count++;
                }
                System.out.println(count);
            }
        });
        thread[i].start();

    }


    public static void main(String[] args) throws InterruptedException{
        thread = new Thread[NUM_OF_THREADS];
        long beginTime = System.nanoTime();

        for(int i =0; i < NUM_OF_THREADS ; i++){
            loopSomeTime(i);
        }
        //I need to wait here

        for(Thread eachThread : thread){
            eachThread.join();
        }

        long endTime = System.nanoTime() - beginTime;
        System.out.println("Time taken: " +endTime/(1000*1000) + " milliseconds");
    }
}

I interpret value of 0x7FFFFFFFL equivalent to value 0x7FFFFFFF for comparison, which is 2147483647

Please help me understand the difference in the delay.

Upvotes: 1

Views: 98

Answers (1)

Jean-Baptiste Yun&#232;s
Jean-Baptiste Yun&#232;s

Reputation: 36401

The code is not the same... Here is the code for int version :

  public void run();
    Code:
       0: iconst_0
       1: istore_1
       2: iconst_0
       3: istore_2
       4: iload_2
       5: ldc           #2                  // int 2147483647
       7: if_icmpge     19
      10: iinc          1, 1
      13: iinc          2, 1
      16: goto          4
      19: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
      22: iload_1
      23: invokevirtual #4                  // Method java/io/PrintStream.println:(I)V
      26: return
}

and here is the code for long version :

  public void run();
    Code:
       0: iconst_0
       1: istore_1
       2: lconst_0
       3: lstore_2
       4: lload_2
       5: ldc2_w        #2                  // long 2147483647l
       8: lcmp
       9: ifge          22
      12: iinc          1, 1
      15: lload_2
      16: lconst_1
      17: ladd
      18: lstore_2
      19: goto          4
      22: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;
      25: iload_1
      26: invokevirtual #5                  // Method java/io/PrintStream.println:(I)V
      29: return
}

You can observe that JVM instructions used are not the same. ints are incremented while longs use arithmetic. Roughly : int code use registers and not the long one.

This explain the difference at least on my computer and probably yours.

It used java :

java version "1.8.0_20"
Java(TM) SE Runtime Environment (build 1.8.0_20-b26)
Java HotSpot(TM) 64-Bit Server VM (build 25.20-b23, mixed mode)

and javac

javac 1.8.0_20

on a MacOSX 10.9 platform

My JVM is 64-bits...

Upvotes: 4

Related Questions