Browse Source

Add a pathfinding benchmark

Example run:

```
$ tools/build_and_run_benchmark.py path_benchmark

--------------------------------------------------------
Benchmark              Time             CPU   Iterations
--------------------------------------------------------
BM_SinglePath       2905 ns         2905 ns       241038
BM_Bridges         65951 ns        65948 ns         9785
BM_NoPath         131397 ns       131390 ns         5247
```
pull/7521/merge
Gleb Mazovetskiy 1 year ago
parent
commit
de28cc3167
  1. 5
      test/CMakeLists.txt
  2. 122
      test/path_benchmark.cpp

5
test/CMakeLists.txt

@ -52,7 +52,9 @@ set(standalone_tests
set(benchmarks
clx_render_benchmark
crawl_benchmark
dun_render_benchmark)
dun_render_benchmark
path_benchmark
)
include(Fixtures.cmake)
@ -99,6 +101,7 @@ target_link_dependencies(format_int_test PRIVATE libdevilutionx_format_int langu
target_link_dependencies(ini_test PRIVATE libdevilutionx_ini app_fatal_for_testing)
target_link_dependencies(parse_int_test PRIVATE libdevilutionx_parse_int)
target_link_dependencies(path_test PRIVATE libdevilutionx_pathfinding libdevilutionx_direction app_fatal_for_testing)
target_link_dependencies(path_benchmark PRIVATE libdevilutionx_pathfinding app_fatal_for_testing)
target_link_dependencies(str_cat_test PRIVATE libdevilutionx_strings)
target_link_dependencies(utf8_test PRIVATE libdevilutionx_utf8)

122
test/path_benchmark.cpp

@ -0,0 +1,122 @@
#include <cstdint>
#include <benchmark/benchmark.h>
#include <utility>
#include "engine/path.h"
#include "engine/point.hpp"
#include "engine/points_in_rectangle_range.hpp"
#include "engine/size.hpp"
namespace devilution {
namespace {
struct Map {
Size size;
const char *data;
char operator[](const Point &p) const { return data[p.y * size.width + p.x]; }
};
std::pair<Point, Point> FindStartDest(const Map &m)
{
Point start, dest;
for (Point p : PointsInRectangle(Rectangle(Point { 0, 0 }, m.size))) {
switch (m[p]) {
case 'S':
start = p;
break;
case 'E':
dest = p;
break;
}
}
return { start, dest };
}
void BenchmarkMap(const Map &map, benchmark::State &state)
{
const auto [start, dest] = FindStartDest(map);
const auto posOk = /*posOk=*/[&map](Point p) { return map[p] != '#'; };
for (auto _ : state) {
int8_t path[MaxPathLength];
int result = FindPath(/*canStep=*/[](Point, Point) { return true; },
posOk, start, dest, path);
benchmark::DoNotOptimize(result);
}
}
void BM_SinglePath(benchmark::State &state)
{
BenchmarkMap(
Map {
Size { 15, 15 },
"###############"
"#...#...#.....#"
"#.#.#.#.#.###.#"
"#S#...#.#.#...#"
"#######.#.#.###"
"##...##.#.#E..#"
"#######.#.###.#"
"###...#...#...#"
"###.#######.###"
"#...###...#...#"
"#.#####.#.###.#"
"#.#...#.#.#...#"
"#.#.#.#.#.#.###"
"#...#...#...###"
"###############" },
state);
}
void BM_Bridges(benchmark::State &state)
{
BenchmarkMap(
Map {
Size { 15, 15 },
"###############"
"#.S...........#"
"#.............#"
"#.............#"
"#.............#"
"#.............#"
"############.##"
"#.............#"
"#.............#"
"#.............#"
"#.............#"
"#.............#"
"###.###########"
"#.....E.......#"
"###############" },
state);
}
void BM_NoPath(benchmark::State &state)
{
BenchmarkMap(
Map {
Size { 15, 15 },
"###############"
"#.S...........#"
"#.............#"
"#.............#"
"#.............#"
"#.............#"
"#.............#"
"#.............#"
"#.............#"
"#.............#"
"#.............#"
"#.............#"
"###############"
"#.....E.......#"
"###############" },
state);
}
BENCHMARK(BM_SinglePath);
BENCHMARK(BM_Bridges);
BENCHMARK(BM_NoPath);
} // namespace
} // namespace devilution
Loading…
Cancel
Save