From 8aeea8a13a6dc2b5f5e3d3e59e920ae8e8a4f2b5 Mon Sep 17 00:00:00 2001 From: Siarhei Fedartsou Date: Thu, 6 Jun 2024 21:13:43 +0200 Subject: [PATCH] wip --- src/benchmarks/bench.cpp | 282 ++++++++++++++++++++++----------------- 1 file changed, 157 insertions(+), 125 deletions(-) diff --git a/src/benchmarks/bench.cpp b/src/benchmarks/bench.cpp index f3e16d744..74e422e0b 100644 --- a/src/benchmarks/bench.cpp +++ b/src/benchmarks/bench.cpp @@ -1,7 +1,7 @@ #include "osrm/match_parameters.hpp" #include "osrm/nearest_parameters.hpp" -#include "osrm/trip_parameters.hpp" #include "osrm/table_parameters.hpp" +#include "osrm/trip_parameters.hpp" #include "engine/engine_config.hpp" #include "util/coordinate.hpp" @@ -21,35 +21,36 @@ #include #include #include +#include #include #include +#include #include #include #include #include -#include -#include using namespace osrm; -namespace { +namespace +{ - -class GPSTraces { -private: +class GPSTraces +{ + private: std::set trackIDs; std::unordered_map> traces; std::vector coordinates; mutable std::mt19937 gen; -public: - GPSTraces(int seed) : gen(std::random_device{}()) { - gen.seed(seed); - } + public: + GPSTraces(int seed) : gen(std::random_device{}()) { gen.seed(seed); } - bool readCSV(const std::string& filename) { + bool readCSV(const std::string &filename) + { std::ifstream file(filename); - if (!file.is_open()) { + if (!file.is_open()) + { std::cerr << "Error opening file: " << filename << std::endl; return false; } @@ -57,8 +58,8 @@ public: std::string line; std::getline(file, line); - - while (std::getline(file, line)) { + while (std::getline(file, line)) + { std::istringstream ss(line); std::string token; @@ -76,25 +77,30 @@ public: longitude = std::stod(token); // handle empty fields - if (std::getline(ss, token, ',')) { + if (std::getline(ss, token, ',')) + { time = token; } trackIDs.insert(trackID); - traces[trackID].emplace_back(osrm::util::Coordinate{osrm::util::FloatLongitude{longitude}, osrm::util::FloatLatitude{latitude}}); - coordinates.emplace_back(osrm::util::Coordinate{osrm::util::FloatLongitude{longitude}, osrm::util::FloatLatitude{latitude}}); + traces[trackID].emplace_back(osrm::util::Coordinate{ + osrm::util::FloatLongitude{longitude}, osrm::util::FloatLatitude{latitude}}); + coordinates.emplace_back(osrm::util::Coordinate{osrm::util::FloatLongitude{longitude}, + osrm::util::FloatLatitude{latitude}}); } file.close(); return true; } - const osrm::util::Coordinate& getRandomCoordinate() const { + const osrm::util::Coordinate &getRandomCoordinate() const + { std::uniform_int_distribution<> dis(0, coordinates.size() - 1); return coordinates[dis(gen)]; } - const std::vector& getRandomTrace() const { + const std::vector &getRandomTrace() const + { std::uniform_int_distribution<> dis(0, trackIDs.size() - 1); auto it = trackIDs.begin(); std::advance(it, dis(gen)); @@ -102,40 +108,42 @@ public: } }; -class Statistics { -public: - void push(double timeMs) { +class Statistics +{ + public: + void push(double timeMs) + { times.push_back(timeMs); sorted = false; } - double mean() { - return sum() / times.size(); - } + double mean() { return sum() / times.size(); } - double sum() { + double sum() + { double sum = 0; - for (auto time : times) { + for (auto time : times) + { sum += time; } return sum; } - double min() { - return *std::min_element(times.begin(), times.end()); - } + double min() { return *std::min_element(times.begin(), times.end()); } - double max() { - return *std::max_element(times.begin(), times.end()); - } + double max() { return *std::max_element(times.begin(), times.end()); } - double percentile(double p) { - const auto& times = getTimes(); + double percentile(double p) + { + const auto × = getTimes(); return times[static_cast(p * times.size())]; } -private: - std::vector getTimes() { - if (!sorted) { + + private: + std::vector getTimes() + { + if (!sorted) + { std::sort(times.begin(), times.end()); sorted = true; } @@ -147,8 +155,9 @@ private: bool sorted = false; }; -void runRouteBenchmark(const OSRM &osrm, const GPSTraces &gpsTraces) { - struct Benchmark +void runRouteBenchmark(const OSRM &osrm, const GPSTraces &gpsTraces) +{ + struct Benchmark { std::string name; size_t coordinates; @@ -160,32 +169,30 @@ void runRouteBenchmark(const OSRM &osrm, const GPSTraces &gpsTraces) { auto run_benchmark = [&](const Benchmark &benchmark) { - Statistics statistics; auto NUM = 10000; for (int i = 0; i < NUM; ++i) { - RouteParameters params; - params.overview = benchmark.overview; - params.steps = benchmark.steps; + RouteParameters params; + params.overview = benchmark.overview; + params.steps = benchmark.steps; - for (size_t i = 0; i < benchmark.coordinates; ++i) - { - params.coordinates.push_back(gpsTraces.getRandomCoordinate()); - } + for (size_t i = 0; i < benchmark.coordinates; ++i) + { + params.coordinates.push_back(gpsTraces.getRandomCoordinate()); + } - if (benchmark.alternatives) - { - params.alternatives = *benchmark.alternatives; - } - - if (benchmark.radius) - { - params.radiuses = std::vector>( - params.coordinates.size(), boost::make_optional(*benchmark.radius)); - } + if (benchmark.alternatives) + { + params.alternatives = *benchmark.alternatives; + } + if (benchmark.radius) + { + params.radiuses = std::vector>( + params.coordinates.size(), boost::make_optional(*benchmark.radius)); + } engine::api::ResultT result = json::Object(); TIMER_START(routes); @@ -198,10 +205,10 @@ void runRouteBenchmark(const OSRM &osrm, const GPSTraces &gpsTraces) { if (rc != Status::Ok || json_result.values.find("routes") == json_result.values.end()) { auto code = std::get(json_result.values["code"]).value; - if (code != "NoSegment") { + if (code != "NoSegment") + { throw std::runtime_error{"Couldn't route"}; } - } } std::cout << benchmark.name << std::endl; @@ -269,32 +276,33 @@ void runRouteBenchmark(const OSRM &osrm, const GPSTraces &gpsTraces) { } } -void runMatchBenchmark(const OSRM& osrm, const GPSTraces& gpsTraces) { - struct Benchmark { +void runMatchBenchmark(const OSRM &osrm, const GPSTraces &gpsTraces) +{ + struct Benchmark + { std::string name; std::optional radius = std::nullopt; }; - auto run_benchmark = [&](const Benchmark &benchmark) { - - + auto run_benchmark = [&](const Benchmark &benchmark) + { Statistics statistics; auto NUM = 1000; - for (int i = 0; i < NUM; ++i) { + for (int i = 0; i < NUM; ++i) + { engine::api::ResultT result = json::Object(); - engine::api::MatchParameters params; - params.coordinates = gpsTraces.getRandomTrace(); - params.radiuses = {}; - if (benchmark.radius) - { - for (size_t index = 0; index < params.coordinates.size(); ++index) + engine::api::MatchParameters params; + params.coordinates = gpsTraces.getRandomTrace(); + params.radiuses = {}; + if (benchmark.radius) { - params.radiuses.emplace_back(*benchmark.radius); + for (size_t index = 0; index < params.coordinates.size(); ++index) + { + params.radiuses.emplace_back(*benchmark.radius); + } } - } - TIMER_START(match); const auto rc = osrm.Match(params, result); @@ -303,9 +311,12 @@ void runMatchBenchmark(const OSRM& osrm, const GPSTraces& gpsTraces) { statistics.push(TIMER_MSEC(match)); auto &json_result = std::get(result); - if (rc != Status::Ok || json_result.values.find("matchings") == json_result.values.end()) { + if (rc != Status::Ok || + json_result.values.find("matchings") == json_result.values.end()) + { auto code = std::get(json_result.values["code"]).value; - if (code != "NoSegment") { + if (code != "NoSegment") + { throw std::runtime_error{"Couldn't route"}; } } @@ -318,33 +329,36 @@ void runMatchBenchmark(const OSRM& osrm, const GPSTraces& gpsTraces) { std::cout << "max: " << statistics.max() << "ms" << std::endl; }; - std::vector benchmarks = { - {"1000 matches, default radius"}, - {"1000 matches, radius=10", 10}, - {"1000 matches, radius=20", 20} - }; + std::vector benchmarks = {{"1000 matches, default radius"}, + {"1000 matches, radius=10", 10}, + {"1000 matches, radius=20", 20}}; - for (const auto &benchmark : benchmarks) { + for (const auto &benchmark : benchmarks) + { run_benchmark(benchmark); } - } -void runNearestBenchmark(const OSRM &osrm, const GPSTraces &gpsTraces) { - struct Benchmark { +void runNearestBenchmark(const OSRM &osrm, const GPSTraces &gpsTraces) +{ + struct Benchmark + { std::string name; std::optional number_of_results = std::nullopt; }; - auto run_benchmark = [&](const Benchmark &benchmark) { + auto run_benchmark = [&](const Benchmark &benchmark) + { Statistics statistics; auto NUM = 10000; - for (int i = 0; i < NUM; ++i) { + for (int i = 0; i < NUM; ++i) + { engine::api::ResultT result = json::Object(); NearestParameters params; params.coordinates.push_back(gpsTraces.getRandomCoordinate()); - if (benchmark.number_of_results) { + if (benchmark.number_of_results) + { params.number_of_results = *benchmark.number_of_results; } @@ -355,9 +369,12 @@ void runNearestBenchmark(const OSRM &osrm, const GPSTraces &gpsTraces) { statistics.push(TIMER_MSEC(nearest)); auto &json_result = std::get(result); - if (rc != Status::Ok || json_result.values.find("waypoints") == json_result.values.end()) { + if (rc != Status::Ok || + json_result.values.find("waypoints") == json_result.values.end()) + { auto code = std::get(json_result.values["code"]).value; - if (code != "NoSegment") { + if (code != "NoSegment") + { throw std::runtime_error{"Couldn't find nearest point"}; } } @@ -370,32 +387,36 @@ void runNearestBenchmark(const OSRM &osrm, const GPSTraces &gpsTraces) { std::cout << "max: " << statistics.max() << "ms" << std::endl; }; - std::vector benchmarks = { - {"10000 nearest, number_of_results=1", 1}, - {"10000 nearest, number_of_results=5", 5}, - {"10000 nearest, number_of_results=10", 10} - }; + std::vector benchmarks = {{"10000 nearest, number_of_results=1", 1}, + {"10000 nearest, number_of_results=5", 5}, + {"10000 nearest, number_of_results=10", 10}}; - for (const auto &benchmark : benchmarks) { + for (const auto &benchmark : benchmarks) + { run_benchmark(benchmark); } } -void runTripBenchmark(const OSRM &osrm, const GPSTraces &gpsTraces) { - struct Benchmark { +void runTripBenchmark(const OSRM &osrm, const GPSTraces &gpsTraces) +{ + struct Benchmark + { std::string name; size_t coordinates; }; - auto run_benchmark = [&](const Benchmark &benchmark) { + auto run_benchmark = [&](const Benchmark &benchmark) + { Statistics statistics; auto NUM = 10000; - for (int i = 0; i < NUM; ++i) { + for (int i = 0; i < NUM; ++i) + { engine::api::ResultT result = json::Object(); TripParameters params; params.roundtrip = true; - for (size_t i = 0; i < benchmark.coordinates; ++i) { + for (size_t i = 0; i < benchmark.coordinates; ++i) + { params.coordinates.push_back(gpsTraces.getRandomCoordinate()); } @@ -406,9 +427,11 @@ void runTripBenchmark(const OSRM &osrm, const GPSTraces &gpsTraces) { statistics.push(TIMER_MSEC(trip)); auto &json_result = std::get(result); - if (rc != Status::Ok || json_result.values.find("trips") == json_result.values.end()) { + if (rc != Status::Ok || json_result.values.find("trips") == json_result.values.end()) + { auto code = std::get(json_result.values["code"]).value; - if (code != "NoSegment") { + if (code != "NoSegment") + { throw std::runtime_error{"Couldn't find trip"}; } } @@ -427,24 +450,30 @@ void runTripBenchmark(const OSRM &osrm, const GPSTraces &gpsTraces) { {"10000 trips, 5 coordinates", 5}, }; - for (const auto &benchmark : benchmarks) { + for (const auto &benchmark : benchmarks) + { run_benchmark(benchmark); } } -void runTableBenchmark(const OSRM &osrm, const GPSTraces &gpsTraces) { - struct Benchmark { +void runTableBenchmark(const OSRM &osrm, const GPSTraces &gpsTraces) +{ + struct Benchmark + { std::string name; size_t coordinates; }; - auto run_benchmark = [&](const Benchmark &benchmark) { + auto run_benchmark = [&](const Benchmark &benchmark) + { Statistics statistics; auto NUM = 1000; - for (int i = 0; i < NUM; ++i) { + for (int i = 0; i < NUM; ++i) + { engine::api::ResultT result = json::Object(); TableParameters params; - for (size_t i = 0; i < benchmark.coordinates; ++i) { + for (size_t i = 0; i < benchmark.coordinates; ++i) + { params.coordinates.push_back(gpsTraces.getRandomCoordinate()); } @@ -455,9 +484,12 @@ void runTableBenchmark(const OSRM &osrm, const GPSTraces &gpsTraces) { statistics.push(TIMER_MSEC(table)); auto &json_result = std::get(result); - if (rc != Status::Ok || json_result.values.find("durations") == json_result.values.end()) { + if (rc != Status::Ok || + json_result.values.find("durations") == json_result.values.end()) + { auto code = std::get(json_result.values["code"]).value; - if (code != "NoSegment") { + if (code != "NoSegment") + { throw std::runtime_error{"Couldn't compute table"}; } } @@ -470,15 +502,14 @@ void runTableBenchmark(const OSRM &osrm, const GPSTraces &gpsTraces) { std::cout << "max: " << statistics.max() << "ms" << std::endl; }; - std::vector benchmarks = { - {"1000 tables, 3 coordinates", 3}, - {"1000 tables, 25 coordinates", 25}, - {"1000 tables, 50 coordinates", 50}, - {"1000 tables, 100 coordinates", 100}, - {"1000 tables, 250 coordinates", 250} - }; + std::vector benchmarks = {{"1000 tables, 3 coordinates", 3}, + {"1000 tables, 25 coordinates", 25}, + {"1000 tables, 50 coordinates", 50}, + {"1000 tables, 100 coordinates", 100}, + {"1000 tables, 250 coordinates", 250}}; - for (const auto &benchmark : benchmarks) { + for (const auto &benchmark : benchmarks) + { run_benchmark(benchmark); } } @@ -490,16 +521,17 @@ try { if (argc < 5) { - std::cerr << "Usage: " << argv[0] << " data.osrm \n"; + std::cerr + << "Usage: " << argv[0] + << " data.osrm \n"; return EXIT_FAILURE; } - // Configure based on a .osrm base path, and no datasets in shared mem from osrm-datastore EngineConfig config; config.storage_config = {argv[1]}; - config.algorithm = std::string{argv[2]} == "mld" ? EngineConfig::Algorithm::MLD - : EngineConfig::Algorithm::CH; + config.algorithm = + std::string{argv[2]} == "mld" ? EngineConfig::Algorithm::MLD : EngineConfig::Algorithm::CH; config.use_shared_memory = false; // Routing machine with several services (such as Route, Table, Nearest, Trip, Match)