diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..b69cb050aa18a056b9753b1aa32368ffc02044d8 --- /dev/null +++ b/benchmark/CMakeLists.txt @@ -0,0 +1,25 @@ +cmake_minimum_required(VERSION 3.6) +project(benchmark-tests) +set(CMAKE_VERBOSE_MAKEFILE ON) +set(CMAKE_COLOR_MAKEFILE ON) + +set(BENCHMARK_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/QueryBuilderTests.cpp) + +add_executable(benchmark-tests ${BENCHMARK_SOURCES}) +target_compile_options(benchmark-tests PRIVATE -Wall -Wextra -g) + +target_link_libraries(benchmark-tests + PRIVATE libhdbpp_headers libhdbpp_timescale_shared_library TangoInterfaceLibrary benchmark gtest) + +target_include_directories(benchmark-tests + PRIVATE ${CMAKE_SOURCE_DIR}/src ${PROJECT_SOURCE_DIR}) + +target_compile_definitions(benchmark-tests + PRIVATE -DDEBUG_ENABLED) + +set_target_properties(benchmark-tests + PROPERTIES + LINK_FLAGS "-Wl,--no-undefined" + CXX_CLANG_TIDY ${DO_CLANG_TIDY} + CXX_STANDARD 14) \ No newline at end of file diff --git a/benchmark/QueryBuilderTests.cpp b/benchmark/QueryBuilderTests.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1a02b5a7702d4d0206aec979ea60e77b9db98d2e --- /dev/null +++ b/benchmark/QueryBuilderTests.cpp @@ -0,0 +1,162 @@ +/* Copyright (C) : 2014-2019 + European Synchrotron Radiation Facility + BP 220, Grenoble 38043, FRANCE + + This file is part of libhdb++timescale. + + libhdb++timescale is free software: you can redistribute it and/or modify + it under the terms of the Lesser GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + libhdb++timescale is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser + GNU General Public License for more details. + + You should have received a copy of the Lesser GNU General Public License + along with libhdb++timescale. If not, see <http://www.gnu.org/licenses/>. */ + +#include "QueryBuilder.hpp" +#include <benchmark/benchmark.h> + +//============================================================================= +//============================================================================= +void bmAllocateQueryBuilder(benchmark::State& state) +{ + // Test - Testing the time it takes to allocate a QueryBuilder, mainly for future test + // reference + hdbpp_internal::LogConfigurator::initLoggingMetrics(false, false); + hdbpp_internal::LogConfigurator::setLoggingLevel(spdlog::level::err); + + for (auto _ : state) + hdbpp_internal::pqxx_conn::QueryBuilder query_builder; +} + +BENCHMARK(bmAllocateQueryBuilder); + +//============================================================================= +//============================================================================= +void bmTraitsComparator(benchmark::State& state) +{ + // TEST - Test the AttributeTraits comparator used in the cache inside QueryBuilder, + // the test is against a full map with every possible tango traits combination + std::map<hdbpp_internal::AttributeTraits, std::string> trait_cache; + + vector<Tango::CmdArgType> types {Tango::DEV_DOUBLE, + Tango::DEV_FLOAT, + Tango::DEV_STRING, + Tango::DEV_LONG, + Tango::DEV_ULONG, + Tango::DEV_LONG64, + Tango::DEV_ULONG64, + Tango::DEV_SHORT, + Tango::DEV_USHORT, + Tango::DEV_BOOLEAN, + Tango::DEV_UCHAR, + Tango::DEV_STATE, + Tango::DEV_ENCODED, + Tango::DEV_ENUM}; + + vector<Tango::AttrWriteType> write_types {Tango::READ, Tango::WRITE, Tango::READ_WRITE, Tango::READ_WITH_WRITE}; + vector<Tango::AttrDataFormat> format_types {Tango::SCALAR, Tango::SPECTRUM, Tango::IMAGE}; + + for (auto &type : types) + { + for (auto &format : format_types) + { + for (auto &write : write_types) + { + // add to the cache for future hits + trait_cache.emplace( + hdbpp_internal::AttributeTraits{write, format, type}, + to_string(write) + to_string(format) + to_string(type)); + } + } + } + + hdbpp_internal::AttributeTraits traits {Tango::READ, Tango::SCALAR, Tango::DEV_DOUBLE}; + + for (auto _ : state) + trait_cache.find(traits); +} + +BENCHMARK(bmTraitsComparator); + +//============================================================================= +//============================================================================= +static void writeTypeArgs(benchmark::internal::Benchmark* b) +{ + vector<Tango::AttrWriteType> write_types {Tango::READ, Tango::WRITE, Tango::READ_WRITE, Tango::READ_WITH_WRITE}; + + for (auto & write_type : write_types) + b->Args({static_cast<int>(write_type)}); +} + +//============================================================================= +//============================================================================= +template<typename T> +void bmStoreDataEventQueryNoCache(benchmark::State& state) +{ + // TEST - Testing how long it takes to build an Insert Data Event query with + // an empty cache (this forces the full string to be built) + hdbpp_internal::LogConfigurator::initLoggingMetrics(false, false); + hdbpp_internal::LogConfigurator::setLoggingLevel(spdlog::level::err); + + hdbpp_internal::AttributeTraits traits + {static_cast<Tango::AttrWriteType>(state.range(0)), Tango::SCALAR, Tango::DEV_DOUBLE}; + + for (auto _ : state) + { + // define the builder here so its cache is always fresh + hdbpp_internal::pqxx_conn::QueryBuilder query_builder; + query_builder.storeDataEventQuery<T>(traits); + } +} + +//============================================================================= +//============================================================================= +template<typename T> +void bmStoreDataEventQueryCache(benchmark::State& state) +{ + // TEST - Testing the full lookup for an Insert Data QueryEvent query when the cache + // map is fully populated + hdbpp_internal::LogConfigurator::initLoggingMetrics(false, false); + hdbpp_internal::LogConfigurator::setLoggingLevel(spdlog::level::err); + + hdbpp_internal::AttributeTraits traits + {static_cast<Tango::AttrWriteType>(state.range(0)), Tango::SCALAR, Tango::DEV_DOUBLE}; + + vector<Tango::CmdArgType> types {Tango::DEV_DOUBLE, + Tango::DEV_FLOAT, + Tango::DEV_STRING, + Tango::DEV_LONG, + Tango::DEV_ULONG, + Tango::DEV_LONG64, + Tango::DEV_ULONG64, + Tango::DEV_SHORT, + Tango::DEV_USHORT, + Tango::DEV_BOOLEAN, + Tango::DEV_UCHAR, + Tango::DEV_STATE, + Tango::DEV_ENCODED, + Tango::DEV_ENUM}; + + vector<Tango::AttrWriteType> write_types {Tango::READ, Tango::WRITE, Tango::READ_WRITE, Tango::READ_WITH_WRITE}; + vector<Tango::AttrDataFormat> format_types {Tango::SCALAR, Tango::SPECTRUM, Tango::IMAGE}; + + hdbpp_internal::pqxx_conn::QueryBuilder query_builder; + + for (auto &type : types) + for (auto &format : format_types) + for (auto &write : write_types) + query_builder.storeDataEventQuery<T>(hdbpp_internal::AttributeTraits{write, format, type}); + + for (auto _ : state) + query_builder.storeDataEventQuery<T>(traits); +} + +BENCHMARK_TEMPLATE(bmStoreDataEventQueryNoCache, bool)->Apply(writeTypeArgs); +BENCHMARK_TEMPLATE(bmStoreDataEventQueryCache, bool)->Apply(writeTypeArgs); + +BENCHMARK_MAIN(); \ No newline at end of file diff --git a/doc/build.md b/doc/build.md index 91d130cad7142884cf8fc9fd7fcd046f46fdc52a..5b0a64efa30f0f2ba714ae56df5cbb65894e20e4 100644 --- a/doc/build.md +++ b/doc/build.md @@ -65,18 +65,20 @@ The following is a list of common useful CMake flags and their use: | Flag | Setting | Default | Description | |------|-----|-----|-----| -| HDBPP_TDB_BUILD_TESTS | ON/OFF | OFF | Build unit tests | -| HDBPP_TDB_BUILD_DEBUG_SYMBOLS | ON/OFF | OFF | Add additional debug systems to the library | -| HDBPP_TDB_ENABLE_CLANG | ON/OFF | OFF | Clang code static analysis, readability, and cppcore guideline enforcement | +| BUILD_UNIT_TESTS | ON/OFF | OFF | Build unit tests | +| BUILD_BENCHMARK_TESTS | ON/OFF | OFF | Build benchmark tests (Forces a Release build) | +| ENABLE_CLANG | ON/OFF | OFF | Clang code static analysis, readability, and cppcore guideline enforcement | ## Running Tests +### Unit Tests + The project has extensive unit tests to ensure its functioning as expect. Build the project with testing enabled: ```bash mkdir -p build cd build -cmake -DHDBPP_TDB_BUILD_TESTS=ON .. +cmake -DBUILD_UNIT_TESTS=ON .. make ``` @@ -103,3 +105,18 @@ To see more options for the unit-test command line binary: ```bash ./bin/unit-tests --help ``` + +### Benchmark Tests + +These are a work in progress to explore future optimisation point. If built, they can be run as follows: + +```bash +mkdir -p build +cd build +cmake -DBUILD_BENCHMARK_TESTS=ON .. +make +``` + +```bash +./benchmark/benchmark-tests +``` \ No newline at end of file