为什么使用堆栈容器比较慢?

时间:2019-01-02 06:23:04

标签: java performance stack

我正在尝试解决问题739,即LeetCode上的每日温度。 https://leetcode.com/problems/daily-temperatures/

我的代码使用了JAVA提供的Stack容器。运行需要60毫秒。这是我的代码:

class Solution {
    public int[] dailyTemperatures(int[] T) {
        int[] ret = new int[T.length];
        Stack<Integer> stack = new Stack<Integer>();
        for(int i=0; i < T.length; i++){
            while(!stack.isEmpty() && T[i] > T[stack.peek()]){
                int index = stack.pop();
                ret[index] = i - index;             
            }
            stack.push(i);
        }
        return ret;
    }
}

这是一个只需6毫秒即可运行的代码:

class Solution {
    public int[] dailyTemperatures(int[] T) {

        int[] temperatures = T;
        if(temperatures == null) return null;

        int[] result = new int[temperatures.length];
        int[] stack = new int[temperatures.length];
        int top = 0;
        stack[top] = -1;

        for(int i = 0; i < temperatures.length; i++) {
            while(stack[top] != -1 && temperatures[i] > temperatures[stack[top]]) {
                int index = stack[top--];
                result[index] = i - index;
            }

            stack[++top] = i;
        }

        return result;
    }
}

为什么使用数组构建堆栈要比使用堆栈容器快?

3 个答案:

答案 0 :(得分:3)

Java的Stack是一个非常老的类,早在JDK 1.0中就引入了。它扩展了Vector,并且所有数据处理方法都是synchronized,从而产生了非常大的性能开销。尽管尚未正式弃用它,但它已经过时了,您真的不应该在这个时代使用它。现代的ArrayDeque提供了相同的功能,而没有同步开销。

答案 1 :(得分:1)

在leetcode环境中测试:

  1. 第一个Stack[Integer]解决方案需要80毫秒才能运行,而将Stack[Integer]更改为ArrayDeque[Integer]则需要31毫秒。这是一个很大的改进,可以证明Stack比现代ArrayDeque慢得多。

请注意,只有pop方法和peeksynchronized,而push不是。

  1. 第二个array[]解决方案需要10毫秒的运行时间。更改为Integer[] 需要19毫秒。因此,我认为自动装箱也是一个因素。

所以没有唯一的原因。

答案 2 :(得分:0)

只有性能分析会准确显示出哪些效果是运行时间变慢的根源。

我最好的客人是为int值创建Boxing-Integer-Intances,以及更复杂的实现

stack.pop() / stack.peek() / stack.push()与基本数组访问相反。

您可以尝试更改阵列版本以改为使用Integer,并查看性能如何变化。