From 9ec4777a7bd6e54a3c0e8a09818187b6fed8f014 Mon Sep 17 00:00:00 2001 From: Petra Baranski Date: Mon, 21 Apr 2025 01:02:07 +0200 Subject: [PATCH] Add benchmark * add benchmark option * updated changelog * added benchmark info to readme * add bench folder to format.py --- CHANGELOG.md | 3 ++- CMakeLists.txt | 7 ++++- README.md | 15 +++++++++++ bench/CMakeLists.txt | 50 +++++++++++++++++++++++++++++++++++ bench/README.md | 14 ++++++++++ bench/main.cpp | 63 ++++++++++++++++++++++++++++++++++++++++++++ tools/format.py | 2 ++ 7 files changed, 152 insertions(+), 2 deletions(-) create mode 100644 bench/CMakeLists.txt create mode 100644 bench/README.md create mode 100644 bench/main.cpp diff --git a/CHANGELOG.md b/CHANGELOG.md index 1795c10..2f90e38 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,10 +13,11 @@ maddy uses [semver versioning](https://semver.org/). * ![**REMOVED**](https://img.shields.io/badge/-REMOVED-%23900) for now removed features. ## Upcoming + * ![**ADDED**](https://img.shields.io/badge/-ADDED-%23099) Correctly parse links with title text, i.e. `[link](http://example.com "example")`. * ![**FIXED**](https://img.shields.io/badge/-FIXED-%23090) Do not create invalid URLs from links with spaces, i.e. `[link](/ABC/some file)`. * ![**FIXED**](https://img.shields.io/badge/-FIXED-%23090) Do not create invalid HTML from links with quotes, i.e. `[link](/ABC/some"file)`. - +* ![**ADDED**](https://img.shields.io/badge/-ADDED-%23099) benchmarks. ## version 1.4.0 2025-03-28 diff --git a/CMakeLists.txt b/CMakeLists.txt index 1481d49..89de83a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,7 @@ if(${MADDY_BUILD_WITH_TESTS}) enable_testing() endif() +option(MADDY_BUILD_WITH_BENCH "enable benchmarks" OFF) option(MADDY_CREATE_PACKAGE "create a package for a version release" OFF) # ------------------------------------------------------------------------------ @@ -49,10 +50,14 @@ if(${MADDY_BUILD_WITH_TESTS}) add_subdirectory(tests) endif() +if(${MADDY_BUILD_WITH_BENCH}) + add_subdirectory(bench) +endif() + # ------------------------------------------------------------------------------ if(${MADDY_CREATE_PACKAGE}) - set(MADDY_PACKAGE_FILES include/ CMakeLists.txt LICENSE) + set(MADDY_PACKAGE_FILES include/ CMakeLists.txt LICENSE AUTHORS) add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/${PROJECT_NAME}-src.zip COMMAND ${CMAKE_COMMAND} -E tar c ${CMAKE_BINARY_DIR}/${PROJECT_NAME}-src.zip --format=zip -- ${MADDY_PACKAGE_FILES} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} diff --git a/README.md b/README.md index 77a128b..eb6a2c4 100644 --- a/README.md +++ b/README.md @@ -98,6 +98,21 @@ make make test # or run the executable in ../build/MaddyTests ``` +## How to run the benchmarks + +To get proper test results, the benchmarks should always be compiled as +release build. + +```shell +git clone https://github.com/progsource/maddy.git +cd maddy +mkdir tmp +cd tmp +cmake -DMADDY_BUILD_WITH_BENCH=ON -DCMAKE_BUILD_TYPE=Release .. +make BUILD_TYPE=Release +../build/maddy_benchmark +``` + ## How to contribute There are different possibilities: diff --git a/bench/CMakeLists.txt b/bench/CMakeLists.txt new file mode 100644 index 0000000..5665411 --- /dev/null +++ b/bench/CMakeLists.txt @@ -0,0 +1,50 @@ +# This project is licensed under the MIT license. For more information see the +# LICENSE file. + +if (UNIX AND NOT APPLE) + execute_process(COMMAND ${CMAKE_CXX_COMPILER} + -fuse-ld=gold -Wl,--version + ERROR_QUIET OUTPUT_VARIABLE ld_version) + if ("${ld_version}" MATCHES "GNU gold") + message(STATUS "Found Gold linker, use faster linker") + set(CMAKE_EXE_LINKER_FLAGS + "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=gold") + set(CMAKE_SHARED_LINKER_FLAGS + "${CMAKE_SHARED_LINKER_FLAGS} -fuse-ld=gold ") + endif() +endif() + +# ------------------------------------------------------------------------------ + +include(FetchContent) + +FetchContent_Declare( + nanobench + GIT_REPOSITORY https://github.com/martinus/nanobench.git + GIT_TAG v4.3.11 + GIT_SHALLOW TRUE +) + +FetchContent_MakeAvailable(nanobench) + +# ------------------------------------------------------------------------------ + +file(GLOB_RECURSE MADDY_BENCHMARK_FILES + ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp +) + +# ------------------------------------------------------------------------------ + +add_executable( + maddy_benchmark + ${MADDY_BENCHMARK_FILES} + ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp +) +target_include_directories(maddy_benchmark PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR} +) +target_link_libraries(maddy_benchmark maddy nanobench::nanobench) +set_target_properties(maddy_benchmark PROPERTIES + CMAKE_CXX_FLAGS + "${CMAKE_CXX_FLAGS} -O2 -Wall -Wno-ignored-qualifiers -Wpedantic -Wextra -Wno-deprecated -fno-exceptions -fno-rtti" +) diff --git a/bench/README.md b/bench/README.md new file mode 100644 index 0000000..1435d1f --- /dev/null +++ b/bench/README.md @@ -0,0 +1,14 @@ +# maddy benchmarks + +## How to run + +The benchmarks have to be run in release mode to give proper results. + +```shell +# in main folder +mkdir tmp +cd tmp +cmake -DMADDY_BUILD_WITH_BENCH=ON -DCMAKE_BUILD_TYPE=Release .. +make BUILD_TYPE=Release +../build/maddy_benchmark +``` diff --git a/bench/main.cpp b/bench/main.cpp new file mode 100644 index 0000000..56e9659 --- /dev/null +++ b/bench/main.cpp @@ -0,0 +1,63 @@ +/* + * This project is licensed under the MIT license. For more information see the + * LICENSE file. + */ +#include +#include +#include +#include +#include + +#define ANKERL_NANOBENCH_IMPLEMENT +#include + +#include "maddy/parser.h" + +int main() +{ + static const std::string markdownFile = "../docs/definitions.md"; + std::stringstream buffer; + + { + std::ifstream file(markdownFile); + + if (!file.good() || !file.is_open()) + { + std::cout << "could not read file at " << markdownFile << std::endl; + return 1; + } + + buffer << file.rdbuf(); + + file.close(); + } + + if (!buffer.good() || buffer.str().empty()) + { + std::cout << "buffer is invalid" << std::endl; + return 2; + } + + // maddy 1.* + std::shared_ptr parser = std::make_shared(); + + // This is the place in the future to compare maddy with other libraries. + // For now it can be used to check if changes in maddy code result in better + // performance. + + ankerl::nanobench::Bench() + .title("maddy test") + .warmup(100) + .relative(true) + .run( + "maddy 1.x", + [&]() + { + buffer.clear(); // clear any error flags + buffer.seekg(0, buffer.beg); + ankerl::nanobench::doNotOptimizeAway(parser->Parse(buffer)); + } + ); + + return 0; +} diff --git a/tools/format.py b/tools/format.py index 09bd1f7..ee0b95d 100644 --- a/tools/format.py +++ b/tools/format.py @@ -60,6 +60,8 @@ def format_files(dry_run): during the actual formatting process. """ patterns = [ + "bench/**/*.h", + "bench/**/*.cpp", "include/**/*.h", "tests/**/*.h", "tests/**/*.cpp",