查找Profiler中记录的特定lambda

时间:2015-10-19 03:52:42

标签: java javafx profiling

我正在编写一个测试应用程序,该应用程序在运行中显示A *搜索,并且运行速度非常慢。我使用VisualVM对其进行了分析,得到了以下结果:

enter image description here

请注意,第三个条目是包含一些长时间运行代码的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占用。

1 个答案:

答案 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));