0

it is a experiment about auto-boxing. The main idea is to execute a mount of pop() and push(), separately with Stack and Stack<Integer>. The core class below:

public class FixedCapcityStack<Item> {
    private final int cap;
    private Item[] arr;
    private int N;
    public FixedCapcityStack(int cap){
        this.cap = cap;
        arr = (Item[]) new Object[cap];
    }

    public void push(Item i){
        arr[N++] = i;
    }

    public Item  pop(){// 不考虑其他其他情况,方便测试
        return arr[--N];
    }

    public boolean isEmpty() {
        return N==0;
    }

    public boolean isFull() {
        return N == cap;
    }
}

public class FixedCapcityStackOfInts {
    private final int cap;
    private int[] arr;
    private int N;
    public FixedCapcityStackOfInts(int cap){
        this.cap = cap;
        arr = new int[cap];
    }

    public void push(int i){
        arr[N++] = i;
    }

    public int  pop(){// 不考虑其他其他情况,方便测试
        return arr[--N];
    }

    public boolean isEmpty() {
        return N==0;
    }

    public boolean isFull() {
        return N == cap;
    }
}

And I use the below code to test:

public static void main(String args[]) {
    Random random = new Random();
    int SIZE = 10;
    FixedCapcityStackOfInts intStack = new FixedCapcityStackOfInts(SIZE);
   //FixedCapcityStack<Integer> intStack = new FixedCapcityStack(SIZE);

    int N = 200;
    while (true) {
        Stopwatch stopwatch = new Stopwatch();
        for (int j = 0; j < N; j++) {
            for (int i = 0; i < SIZE; i++) {
                intStack.push(random.nextInt());
            }

            for (int i = 0; i < SIZE; i++) {
                int k = intStack.pop();
            }
        }
        System.out.printf("N: %d, elapseTime: %f \n", N, stopwatch.elapsedTime());
        N*=2;
    }
}

The result of stack with no generic is

N: 100, elapseTime: 0.033000s
N: 200, elapseTime: 0.026000s
N: 400, elapseTime: 0.025000s
N: 800, elapseTime: 0.047000s
N: 1600, elapseTime: 0.124000s
N: 3200, elapseTime: 0.238000s
N: 6400, elapseTime: 0.490000s
N: 12800, elapseTime: 0.731000s
N: 25600, elapseTime: 1.437000s
N: 51200, elapseTime: 2.951000s
N: 102400, elapseTime: 5.891000s
N: 204800, elapseTime: 11.810000s
N: 409600, elapseTime: 23.699000s
N: 819200, elapseTime: 46.441000s

The result of Stack<Integer> is:

N: 100, elapseTime: 0.034000s
N: 200, elapseTime: 0.018000s
N: 400, elapseTime: 0.049000s
N: 800, elapseTime: 0.053000s
N: 1600, elapseTime: 0.150000s
N: 3200, elapseTime: 0.251000s
N: 6400, elapseTime: 0.536000s
N: 12800, elapseTime: 0.885000s
N: 25600, elapseTime: 1.570000s
N: 51200, elapseTime: 3.181000s
N: 102400, elapseTime: 6.321000s
N: 204800, elapseTime: 12.923000s
N: 409600, elapseTime: 25.643000s
N: 819200, elapseTime: 51.373000s

The performance doesn't bad. But when you use the following code to test:

long start = System.currentTimeMillis();
Long sum = 0L;
for (long i = 0; i < Integer.MAX_VALUE; i++) {
    sum += i;
}
long end = System.currentTimeMillis();
System.out.println("Long sum took: " + (end - start) + " milliseconds");

start  = System.currentTimeMillis();
long sum2 = 0L;
for (long i = 0; i <Integer.MAX_VALUE; i++) {
    sum2 += i;
}
end = System.currentTimeMillis();
System.out.println("long sum took: " + (end - start) + " milliseconds");

The result is :

 Long sum took: 8043 milliseconds
 long sum took: 793 milliseconds

oh my god! Why the two results are different from each other. Of course,the conclusion about auto boxing from the two results are also different. It confuses me a lot.

Nicolas Filotto
  • 43,537
  • 11
  • 94
  • 122
user13457
  • 23
  • 3

1 Answers1

0

In the first example, there's a lot of overhead caused by the stack objects themselves. Boxed primitives make the class slower, but there are other bottlenecks to consider.

In the second example there is very little overhead, making the performance difference between the boxed versus un-boxed primitive much more noticeable.

flakes
  • 21,558
  • 8
  • 41
  • 88
  • 1
    That, and also the fact that in the first loop some iterations were executing interpreted bytecode whereas in the second loop all iterations were executing JIT-compiled code. – Klitos Kyriacou Oct 04 '16 at 14:34
  • I think i got the reason why there is a big difference between the two experiments. – user13457 Oct 05 '16 at 13:14