/*
* Copyright (c) 2014, Oracle America, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of Oracle nor the names of its contributors may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package squidpony.performance;
import com.badlogic.gdx.ai.pfa.*;
import com.badlogic.gdx.ai.pfa.indexed.IndexedAStarPathFinder;
import com.badlogic.gdx.ai.pfa.indexed.IndexedGraph;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.ObjectIntMap;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import squidpony.performance.alternate.OldDijkstraMap;
import squidpony.performance.alternate.OldCustomDijkstraMap;
import squidpony.squidmath.AStarSearch;
import squidpony.squidai.CustomDijkstraMap;
import squidpony.squidai.DijkstraMap;
import squidpony.squidgrid.Adjacency;
import squidpony.squidgrid.Direction;
import squidpony.squidgrid.mapping.DungeonGenerator;
import squidpony.squidgrid.mapping.DungeonUtility;
import squidpony.squidgrid.mapping.SerpentMapGenerator;
import squidpony.squidmath.*;
import java.util.Collections;
import java.util.Queue;
import java.util.concurrent.TimeUnit;
/**
* Times:
* Benchmark Mode Cnt Score Error Units
* DijkstraBenchmark.measurePathAStar avgt 3 5083.488 ± 997.886 ms/op
* DijkstraBenchmark.measurePathAStar2 avgt 3 485.639 ± 21.579 ms/op
* DijkstraBenchmark.measurePathCustomDijkstra avgt 3 104.302 ± 12.242 ms/op
* DijkstraBenchmark.measurePathDijkstra avgt 3 113.594 ± 4.293 ms/op
* DijkstraBenchmark.measurePathGDXAStar avgt 3 29.972 ± 0.370 ms/op
* DijkstraBenchmark.measureTinyPathAStar2 avgt 3 7.099 ± 0.192 ms/op
* DijkstraBenchmark.measureTinyPathCustomDijkstra avgt 3 12.209 ± 22.552 ms/op
* DijkstraBenchmark.measureTinyPathDijkstra avgt 3 25.559 ± 1.930 ms/op
* DijkstraBenchmark.measureTinyPathGDXAStar avgt 3 1.119 ± 0.100 ms/op
*
* December 21 2016, different hardware:
* Benchmark Mode Cnt Score Error Units
* DijkstraBenchmark.measurePathAStar avgt 3 5850.311 ± 404.757 ms/op
* DijkstraBenchmark.measurePathAStar2 avgt 3 560.238 ± 189.030 ms/op
* DijkstraBenchmark.measurePathBoxedDijkstra avgt 3 209.980 ± 66.035 ms/op // not tested before
* DijkstraBenchmark.measurePathCustomDijkstra avgt 3 121.427 ± 38.127 ms/op
* DijkstraBenchmark.measurePathDijkstra avgt 3 130.467 ± 88.321 ms/op
* DijkstraBenchmark.measurePathGDXAStar avgt 3 34.108 ± 17.086 ms/op
* DijkstraBenchmark.measureTinyPathAStar2 avgt 3 8.278 ± 1.149 ms/op
* DijkstraBenchmark.measureTinyPathCustomDijkstra avgt 3 14.551 ± 14.218 ms/op
* DijkstraBenchmark.measureTinyPathDijkstra avgt 3 28.658 ± 13.810 ms/op
* DijkstraBenchmark.measureTinyPathGDXAStar avgt 3 1.245 ± 0.265 ms/op
*
* Benchmark Mode Cnt Score Error Units
* DijkstraBenchmark.measurePathAStar2 avgt 3 53480.665 ± 18729.945 ms/op
* DijkstraBenchmark.measurePathCustomDijkstra avgt 3 2723.753 ± 925.120 ms/op
* DijkstraBenchmark.measurePathDijkstra avgt 3 3074.905 ± 540.216 ms/op
* DijkstraBenchmark.measurePathGDXAStar avgt 3 1107.468 ± 1023.402 ms/op
* DijkstraBenchmark.measurePathOptDijkstra avgt 3 1785.539 ± 292.576 ms/op // used int distances
* DijkstraBenchmark.measureScanCustomDijkstra avgt 3 2646.074 ± 265.886 ms/op
* DijkstraBenchmark.measureScanDijkstra avgt 3 2934.270 ± 299.965 ms/op
* DijkstraBenchmark.measureScanOptDijkstra avgt 3 1681.452 ± 502.217 ms/op // used int distances
* DijkstraBenchmark.measureTinyPathAStar2 avgt 3 54.409 ± 6.358 ms/op
* DijkstraBenchmark.measureTinyPathCustomDijkstra avgt 3 515.103 ± 483.498 ms/op
* DijkstraBenchmark.measureTinyPathDijkstra avgt 3 612.636 ± 105.496 ms/op
* DijkstraBenchmark.measureTinyPathGDXAStar avgt 3 5.473 ± 1.066 ms/op
* DijkstraBenchmark.measureTinyPathOptDijkstra avgt 3 126.647 ± 25.790 ms/op // used int distances
*
* Benchmark Mode Cnt Score Error Units
* DijkstraBenchmark.measurePathCustomDijkstra avgt 3 2622.331 ± 398.498 ms/op
* DijkstraBenchmark.measurePathDijkstra avgt 3 2890.659 ± 621.237 ms/op
* DijkstraBenchmark.measurePathGDXAStar avgt 3 1028.622 ± 80.724 ms/op
* DijkstraBenchmark.measurePathOptDijkstra avgt 3 1685.116 ± 138.863 ms/op
* DijkstraBenchmark.measureScanCustomDijkstra avgt 3 2559.513 ± 475.556 ms/op
* DijkstraBenchmark.measureScanDijkstra avgt 3 2851.652 ± 760.477 ms/op
* DijkstraBenchmark.measureScanOptDijkstra avgt 3 1349.320 ± 102.441 ms/op
* DijkstraBenchmark.measureTinyPathCustomDijkstra avgt 3 490.634 ± 69.431 ms/op
* DijkstraBenchmark.measureTinyPathDijkstra avgt 3 629.138 ± 153.702 ms/op
* DijkstraBenchmark.measureTinyPathGDXAStar avgt 3 5.444 ± 0.473 ms/op
* DijkstraBenchmark.measureTinyPathOptDijkstra avgt 3 159.189 ± 15.194 ms/op
*
* Benchmark Mode Cnt Score Error Units
* DijkstraBenchmark.measurePathCustomDijkstra avgt 3 3004.285 ± 632.953 ms/op
* DijkstraBenchmark.measurePathDijkstra avgt 3 1328.862 ± 285.102 ms/op //with "NextDijkstraMap" update
* DijkstraBenchmark.measurePathGDXAStar avgt 3 1207.328 ± 441.112 ms/op
* DijkstraBenchmark.measurePathOldDijkstra avgt 3 2463.782 ± 534.747 ms/op
* DijkstraBenchmark.measurePathOptDijkstra avgt 3 1957.263 ± 553.280 ms/op
* DijkstraBenchmark.measureScanCustomDijkstra avgt 3 2909.871 ± 636.707 ms/op
* DijkstraBenchmark.measureScanDijkstra avgt 3 1232.099 ± 393.546 ms/op //with "NextDijkstraMap" update
* DijkstraBenchmark.measureScanOldDijkstra avgt 3 2270.479 ± 961.130 ms/op
* DijkstraBenchmark.measureScanOptDijkstra avgt 3 1566.125 ± 218.588 ms/op
* DijkstraBenchmark.measureTinyPathCustomDijkstra avgt 3 516.101 ± 199.369 ms/op
* DijkstraBenchmark.measureTinyPathDijkstra avgt 3 189.029 ± 54.750 ms/op //with "NextDijkstraMap" update
* DijkstraBenchmark.measureTinyPathGDXAStar avgt 3 5.834 ± 1.558 ms/op
* DijkstraBenchmark.measureTinyPathOldDijkstra avgt 3 676.074 ± 138.026 ms/op
* DijkstraBenchmark.measureTinyPathOptDijkstra avgt 3 174.504 ± 36.419 ms/op
*
* This next section seems slower all around, probably because the group requires the number the calculations return to
* be printed (preventing the compiler from omitting certain parts as dead code). This should be more accurate.
*
* Benchmark Mode Cnt Score Error Units
* DijkstraBenchmark.measurePathCustomDijkstra avgt 3 5578.118 ± 1638.982 ms/op
* DijkstraBenchmark.measurePathDijkstra avgt 3 1412.226 ± 116.214 ms/op //woo! (long paths here)
* DijkstraBenchmark.measurePathGDXAStar avgt 3 2291.534 ± 526.744 ms/op //not the best any more!
* DijkstraBenchmark.measurePathOldDijkstra avgt 3 4269.398 ± 258.163 ms/op
* DijkstraBenchmark.measurePathOptDijkstra avgt 3 3608.808 ± 314.844 ms/op
* DijkstraBenchmark.measureScanCustomDijkstra avgt 3 2621.239 ± 61.222 ms/op
* DijkstraBenchmark.measureScanDijkstra avgt 3 1198.388 ± 245.992 ms/op
* DijkstraBenchmark.measureScanOldDijkstra avgt 3 2007.153 ± 713.720 ms/op
* DijkstraBenchmark.measureScanOptDijkstra avgt 3 1429.810 ± 293.400 ms/op
* DijkstraBenchmark.measureTinyPathCustomDijkstra avgt 3 962.297 ± 168.867 ms/op
* DijkstraBenchmark.measureTinyPathDijkstra avgt 3 185.928 ± 110.203 ms/op //not as good on short paths
* DijkstraBenchmark.measureTinyPathGDXAStar avgt 3 12.453 ± 3.873 ms/op
* DijkstraBenchmark.measureTinyPathOldDijkstra avgt 3 1362.067 ± 176.038 ms/op
* DijkstraBenchmark.measureTinyPathOptDijkstra avgt 3 376.765 ± 34.868 ms/op
*/
public class DijkstraBenchmark {
public static final int DIMENSION = 128, PATH_LENGTH = (DIMENSION - 2) * (DIMENSION - 2);
public static DungeonGenerator dungeonGen =
new DungeonGenerator(DIMENSION, DIMENSION, new StatefulRNG(0x1337BEEFDEAL));
public static SerpentMapGenerator serpent = new SerpentMapGenerator(DIMENSION, DIMENSION,
new StatefulRNG(0x1337BEEFDEAL));
public static char[][] map;
public static double[][] astarMap;
public static GreasedRegion floors;
public static double floorCount;
public static Coord[][] nearbyMap;
public static int[] customNearbyMap;
public static Adjacency adj;
static {
serpent.putWalledBoxRoomCarvers(1);
map = dungeonGen.generate(serpent.generate());
floors = new GreasedRegion(map, '.');
floorCount = floors.size();
System.out.println("Floors: " + floorCount);
System.out.println("Percentage walkable: " + floorCount * 100.0 / (DIMENSION * DIMENSION) + "%");
astarMap = DungeonUtility.generateAStarCostMap(map, Collections.<Character, Double>emptyMap(), 1);
nearbyMap = new Coord[DIMENSION][DIMENSION];
customNearbyMap = new int[DIMENSION * DIMENSION];
GreasedRegion tmp = new GreasedRegion(DIMENSION, DIMENSION);
adj = new Adjacency.BasicAdjacency(DIMENSION, DIMENSION, DijkstraMap.Measurement.CHEBYSHEV);
adj.blockingRule = 2;
StatefulRNG srng = new StatefulRNG(0x1337BEEF1337CA77L);
Coord c;
for (int i = 1; i < DIMENSION - 1; i++) {
for (int j = 1; j < DIMENSION - 1; j++) {
if(map[i][j] == '#')
continue;
c = tmp.empty().insert(i, j).flood(floors, 8).remove(i, j).singleRandom(srng);
nearbyMap[i][j] = c;
customNearbyMap[adj.composite(i, j, 0, 0)] = adj.composite(c.x, c.y, 0, 0);
}
}
}
public long doScanDijkstra()
{
DijkstraMap dijkstra = new DijkstraMap(
map, DijkstraMap.Measurement.CHEBYSHEV, new StatefulRNG(0x1337BEEF));
dijkstra.setBlockingRequirement(0);
long scanned = 0;
for (int x = 1; x < DIMENSION - 1; x++) {
for (int y = 1; y < DIMENSION - 1; y++) {
if (map[x][y] == '#')
continue;
dijkstra.setGoal(x, y);
dijkstra.scan(null);
dijkstra.clearGoals();
dijkstra.resetMap();
scanned++;
}
}
return scanned;
}
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public void measureScanDijkstra() throws InterruptedException {
System.out.println(doScanDijkstra());
}
public long doScanCustomDijkstra()
{
CustomDijkstraMap dijkstra = new CustomDijkstraMap(
map, adj, new StatefulRNG(0x1337BEEF));
long scanned = 0;
for (int x = 1; x < DIMENSION - 1; x++) {
for (int y = 1; y < DIMENSION - 1; y++) {
if (map[x][y] == '#')
continue;
dijkstra.setGoal(adj.composite(x, y, 0, 0));
dijkstra.scan(null);
dijkstra.clearGoals();
dijkstra.resetMap();
scanned++;
}
}
return scanned;
}
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public void measureScanCustomDijkstra() throws InterruptedException {
System.out.println(doScanCustomDijkstra());
}
public long doScanOldCustomDijkstra()
{
OldCustomDijkstraMap dijkstra = new OldCustomDijkstraMap(
map, adj, new StatefulRNG(0x1337BEEF));
long scanned = 0;
for (int x = 1; x < DIMENSION - 1; x++) {
for (int y = 1; y < DIMENSION - 1; y++) {
if (map[x][y] == '#')
continue;
dijkstra.setGoal(adj.composite(x, y, 0, 0));
dijkstra.scan(null);
dijkstra.clearGoals();
dijkstra.resetMap();
scanned++;
}
}
return scanned;
}
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public void measureScanOldCustomDijkstra() throws InterruptedException {
System.out.println(doScanOldCustomDijkstra());
}
public long doScanOldDijkstra()
{
OldDijkstraMap dijkstra = new OldDijkstraMap(
map, new StatefulRNG(0x1337BEEF));
dijkstra.setBlockingRequirement(0);
long scanned = 0;
for (int x = 1; x < DIMENSION - 1; x++) {
for (int y = 1; y < DIMENSION - 1; y++) {
if (map[x][y] == '#')
continue;
dijkstra.setGoal(x, y);
dijkstra.scan(null);
dijkstra.clearGoals();
dijkstra.resetMap();
scanned++;
}
}
return scanned;
}
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public void measureScanOldDijkstra() throws InterruptedException {
System.out.println(doScanOldDijkstra());
}
public long doScanGreased()
{
Coord[] goals = new Coord[1];
long scanned = 0;
for (int x = 1; x < DIMENSION - 1; x++) {
for (int y = 1; y < DIMENSION - 1; y++) {
if (map[x][y] == '#')
continue;
goals[0] = Coord.get(x, y);
scanned += GreasedRegion.dijkstraScan8way(map, goals).length;
}
}
return scanned / DIMENSION;
}
//@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public void measureScanGreased() throws InterruptedException {
System.out.println(doScanGreased());
}
public long doPathDijkstra()
{
DijkstraMap dijkstra = new DijkstraMap(
map, DijkstraMap.Measurement.CHEBYSHEV, new StatefulRNG(0x1337BEEF));
dijkstra.setBlockingRequirement(0);
Coord r;
Coord[] tgts = new Coord[1];
long scanned = 0;
DungeonUtility utility = new DungeonUtility(new StatefulRNG(0x1337BEEFDEAL));
for (int x = 1; x < DIMENSION - 1; x++) {
for (int y = 1; y < DIMENSION - 1; y++) {
if (map[x][y] == '#')
continue;
// this should ensure no blatant correlation between R and W
utility.rng.setState((x << 22) | (y << 16) | (x * y));
((StatefulRNG) dijkstra.rng).setState((x << 20) | (y << 14) | (x * y));
r = floors.singleRandom(utility.rng);
tgts[0] = Coord.get(x, y);
dijkstra.findPath(PATH_LENGTH, null, null, r, tgts);
dijkstra.clearGoals();
scanned += dijkstra.path.size();
}
}
return scanned;
}
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public void measurePathDijkstra() throws InterruptedException {
System.out.println(doPathDijkstra() / floorCount);
doPathDijkstra();
}
public long doTinyPathDijkstra()
{
DijkstraMap dijkstra = new DijkstraMap(
map, DijkstraMap.Measurement.CHEBYSHEV, new StatefulRNG(0x1337BEEF));
dijkstra.setBlockingRequirement(0);
Coord r;
long scanned = 0;
Coord[] tgts = new Coord[1];
for (int x = 1; x < DIMENSION - 1; x++) {
for (int y = 1; y < DIMENSION - 1; y++) {
if (map[x][y] == '#')
continue;
((StatefulRNG) dijkstra.rng).setState((x << 20) | (y << 14) | (x * y));
r = nearbyMap[x][y];
tgts[0] = Coord.get(x, y);
dijkstra.findPath(9, 9, null, null, r, tgts);
dijkstra.clearGoals();
dijkstra.resetMap();
scanned += dijkstra.path.size();
}
}
return scanned;
}
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public void measureTinyPathDijkstra() throws InterruptedException {
System.out.println(doTinyPathDijkstra() / floorCount);
doTinyPathDijkstra();
}
public long doPathCustomDijkstra()
{
CustomDijkstraMap dijkstra = new CustomDijkstraMap(
map, adj, new StatefulRNG(0x1337BEEF));
Coord r;
int p;
long scanned = 0;
DungeonUtility utility = new DungeonUtility(new StatefulRNG(0x1337BEEFDEAL));
int[] tgts = new int[1];
for (int x = 1; x < DIMENSION - 1; x++) {
for (int y = 1; y < DIMENSION - 1; y++) {
if (map[x][y] == '#')
continue;
// this should ensure no blatant correlation between R and W
utility.rng.setState((x << 22) | (y << 16) | (x * y));
((StatefulRNG) dijkstra.rng).setState((x << 20) | (y << 14) | (x * y));
r = floors.singleRandom(utility.rng);
p = adj.composite(r.x, r.y, 0, 0);
tgts[0] = adj.composite(x, y, 0, 0);
dijkstra.findPath(PATH_LENGTH, null, null, p, tgts);
dijkstra.clearGoals();
dijkstra.resetMap();
scanned += dijkstra.path.size;
}
}
return scanned;
}
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public void measurePathCustomDijkstra() throws InterruptedException {
System.out.println(doPathCustomDijkstra() / floorCount);
doPathCustomDijkstra();
}
public long doPathOldCustomDijkstra()
{
OldCustomDijkstraMap dijkstra = new OldCustomDijkstraMap(
map, adj, new StatefulRNG(0x1337BEEF));
Coord r;
int p;
long scanned = 0;
int[] tgts = new int[1];
DungeonUtility utility = new DungeonUtility(new StatefulRNG(0x1337BEEFDEAL));
for (int x = 1; x < DIMENSION - 1; x++) {
for (int y = 1; y < DIMENSION - 1; y++) {
if (map[x][y] == '#')
continue;
// this should ensure no blatant correlation between R and W
utility.rng.setState((x << 22) | (y << 16) | (x * y));
((StatefulRNG) dijkstra.rng).setState((x << 20) | (y << 14) | (x * y));
r = floors.singleRandom(utility.rng);
p = adj.composite(r.x, r.y, 0, 0);
tgts[0] = adj.composite(x, y, 0, 0);
dijkstra.findPath(PATH_LENGTH, null, null, p, tgts);
dijkstra.clearGoals();
dijkstra.resetMap();
scanned += dijkstra.path.size;
}
}
return scanned;
}
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public void measurePathOldCustomDijkstra() throws InterruptedException {
System.out.println(doPathOldCustomDijkstra() / floorCount);
doPathOldCustomDijkstra();
}
public long doPathOldDijkstra()
{
OldDijkstraMap dijkstra = new OldDijkstraMap(
map, new StatefulRNG(0x1337BEEF));
dijkstra.setBlockingRequirement(0);
Coord r;
long scanned = 0;
Coord[] tgts = new Coord[1];
DungeonUtility utility = new DungeonUtility(new StatefulRNG(0x1337BEEFDEAL));
for (int x = 1; x < DIMENSION - 1; x++) {
for (int y = 1; y < DIMENSION - 1; y++) {
if (map[x][y] == '#')
continue;
// this should ensure no blatant correlation between R and W
utility.rng.setState((x << 22) | (y << 16) | (x * y));
((StatefulRNG) dijkstra.rng).setState((x << 20) | (y << 14) | (x * y));
r = floors.singleRandom(utility.rng);
tgts[0] = Coord.get(x, y);
dijkstra.findPath(PATH_LENGTH, null, null, r, tgts);
dijkstra.clearGoals();
scanned += dijkstra.path.size();
}
}
return scanned;
}
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public void measurePathOldDijkstra() throws InterruptedException {
System.out.println(doPathOldDijkstra() / floorCount);
doPathOldDijkstra();
}
public long doTinyPathOldDijkstra()
{
OldDijkstraMap dijkstra = new OldDijkstraMap(
map, OldDijkstraMap.Measurement.CHEBYSHEV, new StatefulRNG(0x1337BEEF));
dijkstra.setBlockingRequirement(0);
Coord r;
long scanned = 0;
Coord[] tgts = new Coord[1];
for (int x = 1; x < DIMENSION - 1; x++) {
for (int y = 1; y < DIMENSION - 1; y++) {
if (map[x][y] == '#')
continue;
((StatefulRNG) dijkstra.rng).setState((x << 20) | (y << 14) | (x * y));
r = nearbyMap[x][y];
tgts[0] = Coord.get(x, y);
dijkstra.findPath(9, 9, null, null, r, tgts);
dijkstra.clearGoals();
dijkstra.resetMap();
scanned += dijkstra.path.size();
}
}
return scanned;
}
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public void measureTinyPathOldDijkstra() throws InterruptedException {
System.out.println(doTinyPathOldDijkstra() / floorCount);
doTinyPathOldDijkstra();
}
public long doTinyPathCustomDijkstra()
{
CustomDijkstraMap dijkstra = new CustomDijkstraMap(
map, adj, new StatefulRNG(0x1337BEEF));
Coord r;
int p;
long scanned = 0;
int[] tgts = new int[1];
for (int x = 1; x < DIMENSION - 1; x++) {
for (int y = 1; y < DIMENSION - 1; y++) {
if (map[x][y] == '#')
continue;
((StatefulRNG) dijkstra.rng).setState((x << 20) | (y << 14) | (x * y));
r = nearbyMap[x][y];
p = adj.composite(r.x, r.y, 0, 0);
tgts[0] = adj.composite(x, y, 0, 0);
dijkstra.findPath(1, 9,null, null, p, tgts);
dijkstra.clearGoals();
dijkstra.resetMap();
scanned += dijkstra.path.size;
}
}
return scanned;
}
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public void measureTinyPathCustomDijkstra() throws InterruptedException {
System.out.println(doTinyPathCustomDijkstra() / floorCount);
doTinyPathCustomDijkstra();
}
public long doTinyPathOldCustomDijkstra()
{
OldCustomDijkstraMap dijkstra = new OldCustomDijkstraMap(
map, adj, new StatefulRNG(0x1337BEEF));
Coord r;
int p;
long scanned = 0;
int[] tgts = new int[1];
for (int x = 1; x < DIMENSION - 1; x++) {
for (int y = 1; y < DIMENSION - 1; y++) {
if (map[x][y] == '#')
continue;
((StatefulRNG) dijkstra.rng).setState((x << 20) | (y << 14) | (x * y));
r = nearbyMap[x][y];
p = adj.composite(r.x, r.y, 0, 0);
tgts[0] = adj.composite(x, y, 0, 0);
dijkstra.findPath(9, 9,null, null, p, tgts);
dijkstra.clearGoals();
dijkstra.resetMap();
scanned += dijkstra.path.size;
}
}
return scanned;
}
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public void measureTinyPathOldCustomDijkstra() throws InterruptedException {
System.out.println(doTinyPathOldCustomDijkstra() / floorCount);
doTinyPathOldCustomDijkstra();
}
public long doScanBoxedDijkstra()
{
squidpony.performance.alternate.DijkstraMap dijkstra = new squidpony.performance.alternate.DijkstraMap(
map, squidpony.performance.alternate.DijkstraMap.Measurement.CHEBYSHEV, new StatefulRNG(0x1337BEEF));
long scanned = 0;
for (int x = 1; x < DIMENSION - 1; x++) {
for (int y = 1; y < DIMENSION - 1; y++) {
if (map[x][y] == '#')
continue;
dijkstra.setGoal(x, y);
dijkstra.scan(null);
dijkstra.clearGoals();
dijkstra.resetMap();
scanned++;
}
}
return scanned;
}
//@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public void measureScanBoxedDijkstra() throws InterruptedException {
System.out.println(doScanBoxedDijkstra());
}
public long doPathBoxedDijkstra()
{
squidpony.performance.alternate.DijkstraMap dijkstra = new squidpony.performance.alternate.DijkstraMap(
map, squidpony.performance.alternate.DijkstraMap.Measurement.CHEBYSHEV, new StatefulRNG(0x1337BEEF));
Coord r;
long scanned = 0;
Coord[] tgts = new Coord[1];
DungeonUtility utility = new DungeonUtility(new StatefulRNG(0x1337BEEFDEAL));
for (int x = 1; x < DIMENSION - 1; x++) {
for (int y = 1; y < DIMENSION - 1; y++) {
if (map[x][y] == '#')
continue;
// this should ensure no blatant correlation between R and W
utility.rng.setState((x << 22) | (y << 16) | (x * y));
((StatefulRNG) dijkstra.rng).setState((x << 20) | (y << 14) | (x * y));
r = floors.singleRandom(utility.rng);
tgts[0] = Coord.get(x, y);
dijkstra.findPath(PATH_LENGTH, null, null, r, tgts);
dijkstra.clearGoals();
dijkstra.resetMap();
scanned += dijkstra.path.size();
}
}
return scanned;
}
//@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public void measurePathBoxedDijkstra() throws InterruptedException {
//System.out.println(doPathBoxedDijkstra());
doPathBoxedDijkstra();
}
public long doPathAStar()
{
squidpony.performance.alternate.AStarSearch astar = new squidpony.performance.alternate.AStarSearch(astarMap, squidpony.performance.alternate.AStarSearch.SearchType.CHEBYSHEV);
Coord r;
long scanned = 0;
DungeonUtility utility = new DungeonUtility(new StatefulRNG(0x1337BEEFDEAL));
Queue<Coord> latestPath;
for (int x = 1; x < DIMENSION - 1; x++) {
for (int y = 1; y < DIMENSION - 1; y++) {
if (map[x][y] == '#')
continue;
// this should ensure no blatant correlation between R and W
utility.rng.setState((x << 22) | (y << 16) | (x * y));
r = floors.singleRandom(utility.rng);
latestPath = astar.path(r, Coord.get(x, y));
scanned+= latestPath.size();
}
}
return scanned;
}
//@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public void measurePathAStar() throws InterruptedException {
System.out.println(doPathAStar() / floorCount);
doPathAStar();
}
public long doPathAStar2()
{
AStarSearch astar = new AStarSearch(astarMap, AStarSearch.SearchType.CHEBYSHEV);
Coord r;
long scanned = 0;
DungeonUtility utility = new DungeonUtility(new StatefulRNG(0x1337BEEFDEAL));
Queue<Coord> latestPath;
for (int x = 1; x < DIMENSION - 1; x++) {
for (int y = 1; y < DIMENSION - 1; y++) {
if (map[x][y] == '#')
continue;
// this should ensure no blatant correlation between R and W
utility.rng.setState((x << 22) | (y << 16) | (x * y));
r = floors.singleRandom(utility.rng);
latestPath = astar.path(r, Coord.get(x, y));
scanned+= latestPath.size();
}
}
return scanned;
}
//@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public void measurePathAStar2() throws InterruptedException {
//System.out.println(doPathAStar2());
doPathAStar2();
}
public long doTinyPathAStar2()
{
AStarSearch astar = new AStarSearch(astarMap, AStarSearch.SearchType.CHEBYSHEV);
Coord r;
long scanned = 0;
DungeonUtility utility = new DungeonUtility(new StatefulRNG(0x1337BEEFDEAL));
Queue<Coord> latestPath;
for (int x = 1; x < DIMENSION - 1; x++) {
for (int y = 1; y < DIMENSION - 1; y++) {
if (map[x][y] == '#')
continue;
// this should ensure no blatant correlation between R and W
utility.rng.setState((x << 22) | (y << 16) | (x * y));
r = nearbyMap[x][y];
latestPath = astar.path(r, Coord.get(x, y));
scanned += latestPath.size();
}
}
return scanned;
}
//@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public void measureTinyPathAStar2() throws InterruptedException {
System.out.println(doTinyPathAStar2() / floorCount);
doTinyPathAStar2();
}
class GridGraph implements IndexedGraph<Coord>
{
public ObjectIntMap<Coord> points = new ObjectIntMap<>(DIMENSION * DIMENSION);
public GridGraph(Coord[] pts)
{
for (int i = 0; i < pts.length; i++) {
points.put(pts[i], i);
}
}
@Override
public int getIndex(Coord node) {
return points.get(node, -1);
}
@Override
public int getNodeCount() {
return points.size;
}
@Override
public Array<Connection<Coord>> getConnections(Coord fromNode) {
Array<Connection<Coord>> conn = new Array<>(false, 8);
if(map[fromNode.x][fromNode.y] != '.')
return conn;
Coord t;
for (int i = 0; i < 8; i++) {
t = fromNode.translate(Direction.OUTWARDS[i]);
if (t.isWithin(DIMENSION, DIMENSION) && map[t.x][t.y] == '.')
conn.add(new DefaultConnection<>(fromNode, t));
}
return conn;
}
}
public long doPathGDXAStar()
{
IndexedAStarPathFinder<Coord> astar = new IndexedAStarPathFinder<Coord>(new GridGraph(floors.asCoords()));
GraphPath<Coord> dgp = new DefaultGraphPath<Coord>(PATH_LENGTH);
Heuristic<Coord> heu = new Heuristic<Coord>() {
@Override
public float estimate(Coord node, Coord endNode) {
return Math.abs(node.x - endNode.x) + Math.abs(node.y - endNode.y);
}
};
Coord r;
long scanned = 0;
DungeonUtility utility = new DungeonUtility(new StatefulRNG(0x1337BEEFDEAL));
for (int x = 1; x < DIMENSION - 1; x++) {
for (int y = 1; y < DIMENSION - 1; y++) {
if (map[x][y] == '#')
continue;
// this should ensure no blatant correlation between R and W
utility.rng.setState((x << 22) | (y << 16) | (x * y));
r = floors.singleRandom(utility.rng);
dgp.clear();
if(astar.searchNodePath(r, Coord.get(x, y), heu, dgp))
scanned+= dgp.getCount();
}
}
return scanned;
}
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public void measurePathGDXAStar() throws InterruptedException {
System.out.println(doPathGDXAStar() / floorCount);
doPathGDXAStar();
}
public long doTinyPathGDXAStar()
{
IndexedAStarPathFinder<Coord> astar = new IndexedAStarPathFinder<Coord>(new GridGraph(floors.asCoords()));
GraphPath<Coord> dgp = new DefaultGraphPath<Coord>(9);
Heuristic<Coord> heu = new Heuristic<Coord>() {
@Override
public float estimate(Coord node, Coord endNode) {
return Math.abs(node.x - endNode.x) + Math.abs(node.y - endNode.y);
}
};
Coord r;
long scanned = 0;
for (int x = 1; x < DIMENSION - 1; x++) {
for (int y = 1; y < DIMENSION - 1; y++) {
if (map[x][y] == '#')
continue;
r = nearbyMap[x][y];
dgp.clear();
if(astar.searchNodePath(r, Coord.get(x, y), heu, dgp))
scanned+= dgp.getCount();
}
}
return scanned;
}
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public void measureTinyPathGDXAStar() throws InterruptedException {
System.out.println(doTinyPathGDXAStar() / floorCount);
doTinyPathGDXAStar();
}
/*
* ============================== HOW TO RUN THIS TEST: ====================================
*
* You are expected to see the different run modes for the same benchmark.
* Note the units are different, scores are consistent with each other.
*
* You can run this test:
*
* a) Via the command line from the squidlib-performance module's root folder:
* $ mvn clean install
* $ java -jar target/benchmarks.jar DijkstraBenchmark -wi 3 -i 3 -f 1 -gc true
*
* (we requested 3 warmup/measurement iterations, single fork, garbage collect between benchmarks)
*
* b) Via the Java API:
* (see the JMH homepage for possible caveats when running from IDE:
* http://openjdk.java.net/projects/code-tools/jmh/)
*/
public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.include(DijkstraBenchmark.class.getSimpleName())
.warmupIterations(3)
.measurementIterations(3)
.forks(1)
.shouldDoGC(true)
.build();
new Runner(opt).run();
}
}
/*
public long doPathPlannedAStar()
{
PlannedAStar astar = new PlannedAStar(astarMap, AStarSearch.SearchType.CHEBYSHEV);
Coord r;
long scanned = 0;
DungeonUtility utility = new DungeonUtility(new StatefulRNG(0x1337BEEFDEAL));
for (int x = 1; x < DIMENSION - 1; x++) {
for (int y = 1; y < DIMENSION - 1; y++) {
if (map[x][y] == '#')
continue;
// this should ensure no blatant correlation between R and W
utility.rng.setState((x << 22) | (y << 16) | (x * y));
r = utility.randomCell(floors);
astar.path(r, Coord.get(x, y));
scanned++;
}
}
return scanned;
}
//@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public void measurePathPlannedAStar() throws InterruptedException {
System.out.println(doPathPlannedAStar());
}
*/