diff --git a/.pkg b/.pkg index 67b285264..cea3d326b 100644 --- a/.pkg +++ b/.pkg @@ -1,3 +1,7 @@ +[benchmark] + url=git@github.com:motis-project/benchmark.git + branch=master + commit=94dc64692fa7e1feb361f5b6b3277fc982953afd [googletest] url=git@github.com:motis-project/googletest.git branch=master diff --git a/.pkg.lock b/.pkg.lock index 03f4c85ac..03e9fb80e 100644 --- a/.pkg.lock +++ b/.pkg.lock @@ -1,4 +1,4 @@ -11896755751842712608 +8112488944730267319 cista 1fb6f1d9bb8ac9fdb4ca648df69695dd819dc07e PEGTL 0d37dcf8f02c12a84fdf521973801a5baab78e8f res b759b93316afeb529b6cb5b2548b24c41e382fb0 @@ -8,6 +8,7 @@ docs 75dc89a53e9c2d78574fc0ffda698e69f1682ed2 fmt dc10f83be70ac2873d5f8d1ce317596f1fd318a2 utl 44ff7ba7e571b02c6c47d3981d722e187b86e576 oh d9eb908452e808179afeb7954e8beaa5b3626c36 +benchmark 94dc64692fa7e1feb361f5b6b3277fc982953afd zlib-ng 68ab3e2d80253ec5dc3c83691d9ff70477b32cd3 boost 73549ebca677fe6214202a1ab580362b4f80e653 doctest 832431f2d9dc77e51cc8b364337c186660bf267d diff --git a/CMakeLists.txt b/CMakeLists.txt index 51684cca1..ad6053adc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -134,3 +134,9 @@ add_executable(nigiri-test ${nigiri-test-files}) target_include_directories(nigiri-test PRIVATE include) target_link_libraries(nigiri-test nigiri gtest ianatzdb-res nigiri-generated) target_compile_options(nigiri-test PRIVATE ${nigiri-compile-options}) + +# --- GOOGLE BENCHMARK --- +file(GLOB_RECURSE nigiri-gbm-files exe/g_bm.cc) +add_executable(nigiri-gbm ${nigiri-gbm-files}) +target_link_libraries(nigiri-gbm PRIVATE nigiri boost-program_options ianatzdb-res benchmark::benchmark pthread) +target_compile_features(nigiri-gbm PUBLIC cxx_std_23) diff --git a/exe/g_bm.cc b/exe/g_bm.cc new file mode 100644 index 000000000..24689e131 --- /dev/null +++ b/exe/g_bm.cc @@ -0,0 +1,99 @@ +#include + +#include "nigiri/query_generator/generator.h" +#include "nigiri/routing/raptor/raptor.h" +#include "nigiri/routing/raptor_search.h" +#include "nigiri/routing/search.h" + +static std::filesystem::path tt_path; + +void generate_queries( + std::vector& queries, + std::uint32_t n_queries, + nigiri::timetable const& tt, + nigiri::query_generation::generator_settings const& gs, + std::int64_t const seed) { + auto qg = nigiri::query_generation::generator{ + tt, gs, static_cast(seed)}; + queries.reserve(n_queries); + for (auto i = 0U; i != n_queries; ++i) { + auto const sdq = qg.random_query(); + if (sdq.has_value()) { + queries.emplace_back(sdq.value()); + } + } +} + +struct benchmark_result { + std::uint64_t q_idx_; + nigiri::routing::routing_result + routing_result_; + nigiri::pareto_set journeys_; + std::chrono::milliseconds total_time_; +}; + +void process_queries( + std::vector const& queries, + std::vector& results, + nigiri::timetable const& tt) { + results.reserve(queries.size()); + std::mutex mutex; + { + struct query_state { + nigiri::routing::search_state ss_; + nigiri::routing::raptor_state rs_; + }; + for (auto i = 0U; i < queries.size(); ++i) { + try { + query_state qs; + auto const total_time_start = std::chrono::steady_clock::now(); + auto const result = nigiri::routing::raptor_search( + tt, nullptr, qs.ss_, qs.rs_, queries[i].q_, + nigiri::direction::kForward); + auto const total_time_stop = std::chrono::steady_clock::now(); + auto const guard = std::lock_guard{mutex}; + results.emplace_back(benchmark_result{ + i, result, *result.journeys_, + std::chrono::duration_cast( + total_time_stop - total_time_start)}); + } catch (std::exception const& e) { + std::cout << e.what(); + } + } + } +} + +static void benchmark_random_queries(benchmark::State& state) { + std::vector results; + ::benchmark::DoNotOptimize(results); + std::vector queries; + ::benchmark::DoNotOptimize(queries); + auto tt = *nigiri::timetable::read(tt_path); + tt.resolve(); + ::benchmark::DoNotOptimize(tt); + nigiri::query_generation::generator_settings gs; + ::benchmark::DoNotOptimize(gs); + generate_queries(queries, 1U, tt, gs, 22); + + for (auto _ : state) { + process_queries(queries, results, tt); + ::benchmark::DoNotOptimize(results); + ::benchmark::DoNotOptimize(queries); + ::benchmark::DoNotOptimize(tt); + ::benchmark::DoNotOptimize(gs); + } +} +BENCHMARK(benchmark_random_queries) + ->MinTime(20.0) + ->Unit(benchmark::kMillisecond); + +int main(int argc, char** argv) { + if (argc <= 1) { + fmt::println("Usage: ./nigiri-gbm [TIMETABLE PATH]"); + return 1; + } + tt_path = argv[1]; + ::benchmark::Initialize(&argc, argv); + ::benchmark::RunSpecifiedBenchmarks(); + return 0; +} \ No newline at end of file diff --git a/include/nigiri/logging.h b/include/nigiri/logging.h index 67e28ee10..e8d8edfca 100644 --- a/include/nigiri/logging.h +++ b/include/nigiri/logging.h @@ -27,7 +27,7 @@ static log_lvl s_verbosity; inline std::string now() { using clock = std::chrono::system_clock; auto const now = clock::to_time_t(clock::now()); - struct tm tmp{}; + struct tm tmp {}; #if _MSC_VER >= 1400 gmtime_s(&tmp, &now); #else diff --git a/src/loader/hrd/service/service.cc b/src/loader/hrd/service/service.cc index ee5eb47e0..b329a0cf5 100644 --- a/src/loader/hrd/service/service.cc +++ b/src/loader/hrd/service/service.cc @@ -139,7 +139,7 @@ void parse_range(std::vector const& spec_lines, std::vector const& stops, std::vector& sections, service::section& begin_to_end, - TargetInformationType service::section::* member, + TargetInformationType service::section::*member, TargetInformationParserFun parse_target_info) { compute_ranges(spec_lines, stops, parse_info, [&](auto const& r) { TargetInformationType target_info = parse_target_info(r.first, r.second); @@ -156,14 +156,14 @@ void parse_range(std::vector const& spec_lines, } template -void parse_range(std::vector const& spec_lines, - range_parse_information const& parse_info, - std::vector const& stops, - std::vector& sections, - service::section& begin_to_end, - std::optional> - service::section::* member, - TargetInformationParserFun parse_target_info) { +void parse_range( + std::vector const& spec_lines, + range_parse_information const& parse_info, + std::vector const& stops, + std::vector& sections, + service::section& begin_to_end, + std::optional> service::section::*member, + TargetInformationParserFun parse_target_info) { compute_ranges(spec_lines, stops, parse_info, [&](auto const& r) { TargetInformationType target_info = parse_target_info(r.first, r.second);