我正在尝试解决问题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;
}
}
为什么使用数组构建堆栈要比使用堆栈容器快?
答案 0 :(得分:3)
Java的Stack
是一个非常老的类,早在JDK 1.0中就引入了。它扩展了Vector
,并且所有数据处理方法都是synchronized
,从而产生了非常大的性能开销。尽管尚未正式弃用它,但它已经过时了,您真的不应该在这个时代使用它。现代的ArrayDeque
提供了相同的功能,而没有同步开销。
答案 1 :(得分:1)
在leetcode环境中测试:
Stack[Integer]
解决方案需要80毫秒才能运行,而将Stack[Integer]
更改为ArrayDeque[Integer]
则需要31毫秒。这是一个很大的改进,可以证明Stack
比现代ArrayDeque
慢得多。请注意,只有pop
方法和peek
是synchronized
,而push
不是。
array[]
解决方案需要10毫秒的运行时间。更改为Integer[]
需要19毫秒。因此,我认为自动装箱也是一个因素。所以没有唯一的原因。
答案 2 :(得分:0)
只有性能分析会准确显示出哪些效果是运行时间变慢的根源。
我最好的客人是为int
值创建Boxing-Integer-Intances,以及更复杂的实现
stack.pop()
/ stack.peek()
/ stack.push()
与基本数组访问相反。
您可以尝试更改阵列版本以改为使用Integer
,并查看性能如何变化。