我刚刚把我所知道的有关Java优化的所有内容都放弃了。 我有以下任务:
给定表示游戏场地和场地上位置的2D数组,在另一个数组中填充玩家可以移动到场地上每个其他位置所需步骤的数量。 玩家可以向上、向下、向左和向右移动。 例如,第一批邻居将是所有1,对角线将是所有2。
在第一次尝试中,我尝试了一个简单的四方洪水填充算法。它非常慢。
其次,我决定摆脱递归并使用一个简单的队列。 它运行得非常好,并且大大提高了速度(大约20倍)。 这里是代码:
private void fillCounterArray(int[] counters, int position) {
Queue<Integer> queue = new ArrayDeque<Integer>(900);
// Obtain the possible destinations from position, check the valid ones
// and add it the stack.
int[] destination = board.getPossibleDestinations(position);
for (int i = 0; i < destination.length; i++) {
if (board.getBoard()[destination[i]] == Board.CLEAR) {
counters[destination[i]] = 1;
queue.add(destination[i]);
}
}
// Now fill up the space.
while (!queue.isEmpty()) {
int pos = queue.remove();
int steps = counters[pos];
destination = board.getPossibleDestinations(pos);
for (int i = 0; i < destination.length; i++) {
int dest = destination[i];
if (board.getBoard()[dest] == Board.CLEAR && (counters[dest] > steps + 1 || counters[dest] == 0)) {
counters[dest] = steps + 1;
queue.add(dest);
}
}
}
}
现在,“常识”告诉我,使用静态数组和int指针进行队列操作会更快。因此,我删除了队列并使用标准的int[]数组。代码相同,除了类似于队列的操作。现在它看起来像这样(你可以看到,我曾经生活在C端 :)):
private void fillCounterArray(int[] counters, int position) {
// Array and its pointer.
int[] queue = new int[900]; // max size of field
int head = 0;
// Obtain the possible destinations from position, check the valid ones
// and add it the stack.
int[] destination = board.getPossibleDestinations(position);
for (int i = 0; i < destination.length; i++) {
if (board.getBoard()[destination[i]] == Board.CLEAR) {
counters[destination[i]] = 1;
queue[head++] = dest[i];
}
}
// Now fill up the space.
while (head > 0) {
int pos = queue[--head];
int steps = counters[pos];
destination = board.getPossibleDestinations(pos);
for (int i = 0; i < destination.length; i++) {
int dest = destination[i];
if (board.getBoard()[dest] == Board.CLEAR && (counters[dest] > steps + 1 || counters[dest] == 0)) {
counters[dest] = steps + 1;
queue[head++] = dest;
}
}
}
}
当我运行这个“优化代码”时,它比使用队列慢得多,只比递归技术快两倍左右。当我将数组声明为实例变量时,几乎没有任何差别。这是怎么可能的?
Queue.offer()
可能会返回 false,这可能解释了差异(请参见 http://docs.oracle.com/javase/6/docs/api/java/util/ArrayDeque.html#offer(E))。 - user180100