所以,我能够在22毫秒内平均解决200x200迷宫(就像没有任何图形的pacman)。我使用了四个邻居(向上,向右,向左和向下)的节点链接列表。我使用了FileWriter,文件阅读器,缓冲区方法,并使用BFS算法从起点到目标进行搜索。如前所述,所有这些任务在200x200迷宫上总共需要22毫秒。 我想知道具体使用Queue接口是否有助于加快这一过程。我知道LinkedList实现了Queue,所以我只使用了LinkedList。有关加快速度的建议吗?
注意:我尽力保持每个方法免于过多的循环。我只在写一个文件时才使用两个for循环。
答案 0 :(得分:1)
如果使用网格和递归,则可以避免实际使用循环。
像
这样的东西public static void main(String... ignored) {
search(2, 2, "..........\n" +
".########.\n" +
"...#......\n" +
"#####.####\n" +
"X.........\n");
}
public static boolean search(int x, int y, String grid) {
String[] rows = grid.split("\n");
char[][] grid2 = new char[rows.length][];
for (int i = 0; i < rows.length; i++) {
String row = rows[i];
grid2[i] = row.toCharArray();
}
return search(x, y, grid2);
}
public static boolean search(int x, int y, char[][] grid) {
if (x < 0 || x >= grid.length || y < 0 || y > grid[0].length)
return false;
char ch = grid[x][y];
if (ch == 'X') {
System.out.println("End " + x + ", " + y);
return true;
}
// - is been here before
// # is a wall.
if (ch == '-' || ch == '#') {
return false;
}
grid[x][y] = '-'; // been here before.
boolean found = search(x - 1, y, grid) || search(x + 1, y, grid)
|| search(x, y - 1, grid) || search(x, y + 1, grid);
grid[x][y] = ch;
if (found)
System.out.println("... " + x + ", " + y);
return found;
}
打印(反向排列以避免创建坐标列表)
End 4, 0
... 4, 1
... 4, 2
... 4, 3
... 4, 4
... 4, 5
... 3, 5
... 2, 5
... 2, 6
... 2, 7
... 2, 8
... 2, 9
... 1, 9
... 0, 9
... 0, 8
... 0, 7
... 0, 6
... 0, 5
... 0, 4
... 0, 3
... 0, 2
... 0, 1
... 0, 0
... 1, 0
... 2, 0
... 2, 1
... 2, 2
答案 1 :(得分:0)
这实际上取决于您使用的访问模式。您将看不到Queue和LinkedList之间的巨大差异。如果按位置访问元素,ArrayList实际上可能更快。
此外,如果您正在查看整个事物的整体表现,您是否已经分解了每个主要部分需要多长时间?例如,将FileReader包装在BufferedReader中可能会显着加快文件读取部分的速度。
答案 2 :(得分:0)
一些直接想到的想法如下,请务必随时测量:
1)将所有数据存储在数组中,并确保以标准“步长”大小迭代数组。这将使CPU更容易预测内存访问。链接列表倾向于将对象分散在内存周围,这使得cpus在需要之前预先获取数据变得更加困难。在等待从主存储器加载数据时,这往往会导致CPU停滞。
2)优化文件io并确保它没有停止。预分配文件的大小有助于在os调整文件大小时防止停顿。内存映射文件也可能有所帮助,但里程确实有所不同。
3)将执行工作的线程固定到CPU上的单个内核。这将最大化CPU缓存命中率,而且我经常看到单独增加5倍。
4)如果您发现自己经常修改数组并检查其长度。请注意,java会在数组内容旁边存储数组长度,因此写入数组元素可能会使包含array.lengt值的同一缓存行无效。如果发生这种情况,那么CPU将停止,因此将长度存储在绝望变量或常量中。
5)检查您的算法是否有重复的工作和流线