2015-10-19 26 views
0

我正在編寫一個測試應用程序,它在操作中顯示A *搜索,並且運行速度非常慢。我異型它使用VisualVM的,並得到了以下結果:查找Profiler中指定的特定lambda

enter image description here

注意的是,第三項是包含一些長期運行的代碼拉姆達。

問題是,我無法在任何地方找到帶有這種簽名的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

見http://stackoverflow.com/questions/29435888/identifying-lambdas-in-stacktrace-in-java-8/29607119#29607119 –

+0

@IngoKegel謝謝。 – Carcigenicate

回答

1

嗯,這是你的lambda$1表達式,因爲「參數列表」。這部分是採用了雙端隊列只有一個,2個雙對象,列表,地圖,長:

new MainLoop(10000, /* THIS -> */ t -> { ... }); 

BTW不做在forEach方法在Stream任何過濾操作。因此請使用Stream::filter

這裏:

reconstructPath(cameFrom, startPos, goalPos).stream() 
      .filter(pathPos != startPos && area.getCellAt(pathPos) == null) 
      .forEach(pathPos -> drawSquare(pathPos, Color.ORANGE)); 
+0

你怎麼知道這是lambda1?它與探查者說的有不同的論點。我不確定第二部分的含義。我正在使用'Stream :: filter'。 – Carcigenicate

+0

@Carcigenicate更新了我的回答 – Flown

+0

啊,我明白了。好點子。我仍然沒有看到主循環是如何處理它所談論的Lambda;它只需要一個「長」和「消費者」。 Lambda是否包含在幕後? – Carcigenicate