From 30fd8c9d2325d0455b945b6797c5c3b9fa1db213 Mon Sep 17 00:00:00 2001 From: elsid Date: Fri, 24 Mar 2023 23:29:21 +0100 Subject: [PATCH] Add benchmarks for RefId serialization and deserialization --- .gitlab-ci.yml | 1 + apps/benchmarks/CMakeLists.txt | 1 + apps/benchmarks/esm/CMakeLists.txt | 15 ++++++ apps/benchmarks/esm/benchrefid.cpp | 82 ++++++++++++++++++++++++++++++ 4 files changed, 99 insertions(+) create mode 100644 apps/benchmarks/esm/CMakeLists.txt create mode 100644 apps/benchmarks/esm/benchrefid.cpp diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 8ef6c5db4b..16a420a8c8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -50,6 +50,7 @@ variables: - if [[ "${BUILD_TESTS_ONLY}" ]]; then ./openmw_test_suite --gtest_output="xml:openmw_tests.xml"; fi - if [[ "${BUILD_TESTS_ONLY}" ]]; then ./openmw-cs-tests --gtest_output="xml:openmw_cs_tests.xml"; fi - if [[ "${BUILD_TESTS_ONLY}" && ! "${BUILD_WITH_CODE_COVERAGE}" ]]; then ./openmw_detournavigator_navmeshtilescache_benchmark; fi + - if [[ "${BUILD_TESTS_ONLY}" && ! "${BUILD_WITH_CODE_COVERAGE}" ]]; then ./openmw_esm_refid_benchmark; fi - ccache -s - df -h - if [[ "${BUILD_WITH_CODE_COVERAGE}" ]]; then gcovr --xml-pretty --exclude-unreachable-branches --print-summary --root "${CI_PROJECT_DIR}" -j $(nproc) -o ../coverage.xml; fi diff --git a/apps/benchmarks/CMakeLists.txt b/apps/benchmarks/CMakeLists.txt index 6a23ac3b37..971a1ecd25 100644 --- a/apps/benchmarks/CMakeLists.txt +++ b/apps/benchmarks/CMakeLists.txt @@ -3,3 +3,4 @@ if(OPENMW_USE_SYSTEM_BENCHMARK) endif() add_subdirectory(detournavigator) +add_subdirectory(esm) diff --git a/apps/benchmarks/esm/CMakeLists.txt b/apps/benchmarks/esm/CMakeLists.txt new file mode 100644 index 0000000000..e7ecfff41b --- /dev/null +++ b/apps/benchmarks/esm/CMakeLists.txt @@ -0,0 +1,15 @@ +openmw_add_executable(openmw_esm_refid_benchmark benchrefid.cpp) +target_link_libraries(openmw_esm_refid_benchmark benchmark::benchmark components) + +if (UNIX AND NOT APPLE) + target_link_libraries(openmw_esm_refid_benchmark ${CMAKE_THREAD_LIBS_INIT}) +endif() + +if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.16 AND MSVC) + target_precompile_headers(openmw_esm_refid_benchmark PRIVATE ) +endif() + +if (BUILD_WITH_CODE_COVERAGE) + target_compile_options(openmw_esm_refid_benchmark PRIVATE --coverage) + target_link_libraries(openmw_esm_refid_benchmark gcov) +endif() diff --git a/apps/benchmarks/esm/benchrefid.cpp b/apps/benchmarks/esm/benchrefid.cpp new file mode 100644 index 0000000000..6b76740602 --- /dev/null +++ b/apps/benchmarks/esm/benchrefid.cpp @@ -0,0 +1,82 @@ +#include + +#include "components/esm/refid.hpp" + +#include +#include +#include +#include +#include + +namespace +{ + constexpr std::size_t refIdsCount = 64 * 1024; + + template + std::string generateText(std::size_t size, Random& random) + { + std::uniform_int_distribution distribution('A', 'z'); + std::string result; + result.reserve(size); + std::generate_n(std::back_inserter(result), size, [&] { return distribution(random); }); + return result; + } + + template + std::vector generateStringRefIds(std::size_t size, Random& random) + { + std::vector result; + result.reserve(refIdsCount); + std::generate_n( + std::back_inserter(result), refIdsCount, [&] { return ESM::StringRefId(generateText(size, random)); }); + return result; + } + + template + std::vector generateSerializedRefIds(const std::vector& generated, Serialize&& serialize) + { + std::vector result; + result.reserve(generated.size()); + for (ESM::RefId refId : generated) + result.push_back(serialize(refId)); + return result; + } + + template + std::vector generateSerializedStringRefIds(std::size_t size, Random& random, Serialize&& serialize) + { + return generateSerializedRefIds(generateStringRefIds(size, random), serialize); + } + + void serializeRefId(benchmark::State& state) + { + std::minstd_rand random; + std::vector refIds = generateStringRefIds(state.range(0), random); + std::size_t i = 0; + for (auto _ : state) + { + benchmark::DoNotOptimize(refIds[i].serialize()); + if (++i >= refIds.size()) + i = 0; + } + } + + void deserializeRefId(benchmark::State& state) + { + std::minstd_rand random; + std::vector serializedRefIds + = generateSerializedStringRefIds(state.range(0), random, [](ESM::RefId v) { return v.serialize(); }); + std::size_t i = 0; + for (auto _ : state) + { + benchmark::DoNotOptimize(ESM::RefId::deserialize(serializedRefIds[i])); + if (++i >= serializedRefIds.size()) + i = 0; + } + } +} + +BENCHMARK(serializeRefId)->RangeMultiplier(4)->Range(8, 64); +BENCHMARK(deserializeRefId)->RangeMultiplier(4)->Range(8, 64); + +BENCHMARK_MAIN();