Javaの最適化について知っていることはすべて窓の外に投げ出しました。私には次のタスクがあります。
競技場とフィールド上の位置を表す2D配列が与えられた場合、別の配列に、プレーヤーがフィールド内の他のすべての位置に到達するために実行できるステップ数を入力します。プレイヤーは上下左右に移動できます。たとえば、最初の隣接線はすべて1で、対角線はすべて2になります。
最初の試みでは、単純な4ウェイフラッドフィルアルゴリズムを試しました。それはひどく遅い。
次に、再帰を取り除き、単純なキューを使用することにしました。それは素敵に機能し、大幅なスピードアップ(非常に約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;
}
}
}
}
この「最適化されたコード」を実行したとき、キューを使用するよりも大幅に遅く、再帰的手法の約2倍の速さしかありませんでした。配列をインスタンス変数として宣言する場合も、ほとんど違いはありません。これはどのように可能ですか?