我正在编写一个测试应用程序,该应用程序在运行中显示A *搜索,并且运行速度非常慢。我使用VisualVM对其进行了分析,得到了以下结果:
请注意,第三个条目是包含一些长时间运行代码的lambda。
问题是,我无法在任何地方找到带有这种签名的lambda。
我有什么方法可以找出它所指的lambda吗?
以下是pacmanTest.FrontierVisual.java
:
package pacmanTest;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Deque;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import utils.Duple;
import utils.MainLoop;
public class FrontierVisual
extends Application {
private Stage stage;
private Scene scene;
private final int areaWidth = 800;
private final int areaHeight = 800;
private final double drawScale = 15;
private Canvas canvas = new Canvas(800, 800);
private GraphicsContext gc = canvas.getGraphicsContext2D();
private final MapArea<Wall> area = new MapArea<>(areaWidth, areaHeight);
private static List<Duple<Integer>> cellsAround(Duple<Integer> pos, List<Duple<Integer>> offsets) {
List<Duple<Integer>> surroundingCells = new ArrayList<>();
offsets.stream()
.map( offset -> pos.map(offset, (x1, x2) -> x1 + x2) )
.forEach(surroundingCells::add);
return surroundingCells;
}
private void drawSquare(Duple<Integer> position, Color color) {
gc.setFill(color);
gc.fillRect(position.getX() * drawScale, position.getY() * drawScale, drawScale, drawScale);
}
@Override
public void start(Stage stage) throws Exception {
this.stage = stage;
BorderPane rootNode = new BorderPane();
scene = new Scene(rootNode);
stage.setScene(scene);
rootNode.setCenter(canvas);
Duple<Integer> startPos = new Duple<Integer>(20, 20);
Duple<Integer> goalPos = new Duple<Integer>(30, 30);
Wall wall = new SolidWall();
/*for (int d = 29; d <= 41; d++) {
int e = d / 2;
area.setCellAt(d, e, wall);
}*/
area.setCellAt(19, 32, wall);
area.setCellAt(20, 31, wall);
area.setCellAt(21, 30, wall);
area.setCellAt(22, 29, wall);
area.setCellAt(23, 28, wall);
area.setCellAt(24, 27, wall);
area.setCellAt(25, 26, wall);
area.setCellAt(26, 25, wall);
area.setCellAt(27, 24, wall);
area.setCellAt(28, 23, wall);
area.setCellAt(29, 22, wall);
area.setCellAt(30, 21, wall);
area.setCellAt(31, 20, wall);
area.setCellAt(32, 19, wall);
Deque<Duple<Integer>> frontier = new ArrayDeque<>();
Map<Duple<Integer>, Duple<Integer>> cameFrom = new HashMap<>();
cameFrom.put(startPos, startPos);
frontier.push(startPos);
final List<Duple<Integer>> fourDirectionOffsets = Collections.unmodifiableList(Arrays.asList(
new Duple<Integer>(1,0), new Duple<Integer>(-1,0), new Duple<Integer>(0,1), new Duple<Integer>(0,-1) ));
MainLoop mainLoop = new MainLoop(10000, t -> {
utils.Utils.clearCanvas(gc);
gc.setFill(Color.STEELBLUE);
Duple<Integer> poppedLocation = frontier.pop();
drawSquare(startPos, Color.BLACK);
drawSquare(goalPos, Color.GREEN);
List<Duple<Integer>> neighbors = cellsAround(poppedLocation, fourDirectionOffsets);
neighbors.stream()
.filter(location -> !cameFrom.containsKey(location) && area.cellIsInBounds(location) && area.getCellAt(location) == null)
.forEach( neighbor -> {
frontier.add(neighbor);
cameFrom.put(neighbor, poppedLocation);
drawSquare(neighbor, Color.CORAL);
});
frontier.stream()
.forEach( frontierPos -> {
drawSquare(frontierPos, Color.BLUE);
});
reconstructPath(cameFrom, startPos, goalPos).stream()
.forEach( pathPos -> {
if (pathPos != startPos && area.getCellAt(pathPos) == null) {
drawSquare(pathPos, Color.ORANGE);
}
});
area.forallNonEmptyCells( (pos, contents) -> {
drawSquare(pos, Color.CHOCOLATE);
});
});
mainLoop.start();
stage.show();
}
private static List<Duple<Integer>> reconstructPath(Map<Duple<Integer>, Duple<Integer>> cameFrom, Duple<Integer> start, Duple<Integer> goal) {
List<Duple<Integer>> path = new ArrayList<>();
path.add(goal);
Duple<Integer> current = goal;
do {
path.add(current);
current = cameFrom.get(current);
} while (current != null && !current.equals(start));
Collections.reverse(path);
return path;
}
public static void main(String[] args) {
launch(args);
}
}
此处的任何想法都将受到赞赏。
旁注: 如果有人知道如何缩短JavaFX画布的绘图时间,那将是非常棒的,因为它是最大的CPU占用。
答案 0 :(得分:1)
因为“参数列表”,这是你的lambda$1
表达式。这部分是唯一使用Deque,2 x Duple,List,Map,Long:
new MainLoop(10000, /* THIS -> */ t -> { ... });
BTW不会在Stream
方法的forEach
中执行任何过滤操作。因此,请使用Stream::filter
。
下面:
reconstructPath(cameFrom, startPos, goalPos).stream()
.filter(pathPos != startPos && area.getCellAt(pathPos) == null)
.forEach(pathPos -> drawSquare(pathPos, Color.ORANGE));