Java的集合堆栈数据结构的效率

时间:2016-04-06 14:48:24

标签: java algorithm performance collections stack

今天我正在编写代码来使用Java中的ArrayList实现Stack数据结构。我扩展了我的代码,比较了我在Stack库中对Stack实现的Stack的效率,结果让我感到有些惊讶。我的意思是我确信我的代码效率会低得多,但在很多情况下我的简单代码执行得更好(如果我理解正确的话)。以下是我写的代码: -

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Stack;

import customexceptions.StackUnderflowException;

public class StackArray<T> {
    private int top=-1;
    private List<T> array = new ArrayList<T>();

    public void push(T object) {
        array.add(object);
        top++;
    }

    public T pop() throws StackUnderflowException {
        if (top == -1) {
            throw new StackUnderflowException();
        }
        return array.remove(top--);
    }

    public T peek() throws StackUnderflowException {
        if (top == -1) {
            throw new StackUnderflowException();
        }
        return array.get(top);
    }

    public boolean isEmpty() {
        return top == -1;
    }

    public static void main(String[] args) throws StackUnderflowException {
        Random random = new Random();
        for (int pow=1; pow<25; pow++) {
            StackArray<Integer> intStack = new StackArray<>();
            int size = 1<<pow;
            int i;
            int randomInt = random.nextInt(10);
            long startTime = System.currentTimeMillis();
            for(i=1; i<=size; i++) {
                intStack.push(i * randomInt);
            }
            i--;

            while(!intStack.isEmpty()) {
                int popedValue = intStack.pop();
                assert popedValue == (i * randomInt);
                i--;
            }
            assert i == 0;
            intStack = null;
            long endTime = System.currentTimeMillis();
            System.out.println("Time taken StackArray for 2^" + pow 
                    + " ints = " + (endTime - startTime) + " ms") ;

            randomInt = random.nextInt(10);
            startTime = System.currentTimeMillis();
            Stack<Integer> collectionStack = new Stack<>();
            for(i=1; i<=size; i++) {
                collectionStack.push(i * randomInt);
            }
            i--;

            while(!collectionStack.isEmpty()) {
                int popedValue = collectionStack.pop();
                assert popedValue == (i * randomInt);
                i--;
            }
            assert i == 0;
            endTime = System.currentTimeMillis();
            System.out.println("Time taken by Collection Stack for 2^" +
                    pow + " int = " + (endTime - startTime) + " ms");
        }
    }
}

以下是我得到的输出: -

Time taken StackArray for 2^1 ints = 0 ms
Time taken by Collection Stack for 2^1 int = 0 ms
Time taken StackArray for 2^2 ints = 0 ms
Time taken by Collection Stack for 2^2 int = 0 ms
Time taken StackArray for 2^3 ints = 0 ms
Time taken by Collection Stack for 2^3 int = 0 ms
Time taken StackArray for 2^4 ints = 0 ms
Time taken by Collection Stack for 2^4 int = 0 ms
Time taken StackArray for 2^5 ints = 1 ms
Time taken by Collection Stack for 2^5 int = 0 ms
Time taken StackArray for 2^6 ints = 0 ms
Time taken by Collection Stack for 2^6 int = 0 ms
Time taken StackArray for 2^7 ints = 0 ms
Time taken by Collection Stack for 2^7 int = 0 ms
Time taken StackArray for 2^8 ints = 0 ms
Time taken by Collection Stack for 2^8 int = 1 ms
Time taken StackArray for 2^9 ints = 0 ms
Time taken by Collection Stack for 2^9 int = 1 ms
Time taken StackArray for 2^10 ints = 0 ms
Time taken by Collection Stack for 2^10 int = 1 ms
Time taken StackArray for 2^11 ints = 0 ms
Time taken by Collection Stack for 2^11 int = 1 ms
Time taken StackArray for 2^12 ints = 2 ms
Time taken by Collection Stack for 2^12 int = 1 ms
Time taken StackArray for 2^13 ints = 3 ms
Time taken by Collection Stack for 2^13 int = 3 ms
Time taken StackArray for 2^14 ints = 5 ms
Time taken by Collection Stack for 2^14 int = 5 ms
Time taken StackArray for 2^15 ints = 3 ms
Time taken by Collection Stack for 2^15 int = 7 ms
Time taken StackArray for 2^16 ints = 9 ms
Time taken by Collection Stack for 2^16 int = 15 ms
Time taken StackArray for 2^17 ints = 12 ms
Time taken by Collection Stack for 2^17 int = 22 ms
Time taken StackArray for 2^18 ints = 7 ms
Time taken by Collection Stack for 2^18 int = 21 ms
Time taken StackArray for 2^19 ints = 16 ms
Time taken by Collection Stack for 2^19 int = 51 ms
Time taken StackArray for 2^20 ints = 28 ms
Time taken by Collection Stack for 2^20 int = 94 ms
Time taken StackArray for 2^21 ints = 58 ms
Time taken by Collection Stack for 2^21 int = 201 ms
Time taken StackArray for 2^22 ints = 111 ms
Time taken by Collection Stack for 2^22 int = 318 ms
Time taken StackArray for 2^23 ints = 2338 ms
Time taken by Collection Stack for 2^23 int = 2189 ms
Time taken StackArray for 2^24 ints = 5940 ms
Time taken by Collection Stack for 2^24 int = 3748 ms

在上面的例子中,您可以找到很多情况,我的Stack算法在推送和弹出操作中花费的时间更少。它有什么具体原因吗?或者这是一个不稳定的结果?或者收藏库可能有改进的范围?

1 个答案:

答案 0 :(得分:1)

您的实现速度更快,因为Stack是线程安全的而您的实现不是,因此您在类Stack中拥有的同步锁增加了您没有的开销在你的班上