Skip to content

Commit 8bc9c4b

Browse files
committed
Improve benchmark structure and run targets
1 parent 205e493 commit 8bc9c4b

13 files changed

Lines changed: 116 additions & 196 deletions

.github/workflows/codspeed.yml

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,17 @@ jobs:
1919
- name: Install build tools and dependencies
2020
run: |
2121
sudo apt-get update
22-
# Install necessary build tools
2322
sudo apt-get install -y cmake g++
24-
# Install required Boost components
25-
sudo apt-get install -y libboost-serialization-dev libboost-graph-dev
2623
2724
- name: Build the benchmark target
2825
run: |
2926
mkdir build
3027
cd build
3128
cmake -DCODSPEED_MODE=instrumentation ..
32-
make -j
29+
cmake --build . -j
3330
3431
- name: Run all benchmarks with CodSpeed
3532
uses: CodSpeedHQ/action@v3
3633
with:
37-
run: build/boost_bench # Path to our executable
34+
run: cd build && make run_all_benchmarks
3835
token: ${{ secrets.CODSPEED_TOKEN }}
39-
# No filter - run all benchmarks

CMakeLists.txt

Lines changed: 46 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,71 @@
11
cmake_minimum_required(VERSION 3.14 FATAL_ERROR)
22
project(boost-bench)
33

4+
# TODO: remove this once the CodSpeed Benchmark is fixed
5+
# Disable -Werror for CodSpeed Benchmark to avoid the unused private field error
6+
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
7+
add_compile_options(-Wno-error=unused-private-field)
8+
elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
9+
add_compile_options(-Wno-error)
10+
endif()
11+
412
set(CMAKE_CXX_STANDARD 17)
513
set(CMAKE_CXX_STANDARD_REQUIRED ON)
14+
if(NOT DEFINED BOOST_VERSION)
15+
set(BOOST_VERSION "1.87.0")
16+
endif()
617

7-
# Option for CodSpeed instrumentation mode
8-
option(CODSPEED_MODE "Build for CodSpeed instrumentation" OFF)
918

10-
# Include FetchContent for downloading Google Benchmark
1119
include(FetchContent)
20+
include(cmake/CPM.cmake)
1221

13-
# Set benchmark download dependencies ON
1422
set(BENCHMARK_DOWNLOAD_DEPENDENCIES ON)
15-
16-
# Download and configure CodSpeed C++ Benchmark
1723
FetchContent_Declare(
1824
google_benchmark
1925
GIT_REPOSITORY https://github.com/CodSpeedHQ/codspeed-cpp
2026
SOURCE_SUBDIR google_benchmark
2127
GIT_TAG v1.0.0
2228
)
29+
FetchContent_MakeAvailable(google_benchmark)
2330

24-
# Configure benchmark options
25-
set(BENCHMARK_ENABLE_TESTING OFF CACHE BOOL "Disable benchmark testing" FORCE)
26-
if(CODSPEED_MODE)
27-
set(BENCHMARK_CODSPEED_MODE "instrumentation" CACHE STRING "CodSpeed mode" FORCE)
28-
message(STATUS "Building with CodSpeed instrumentation enabled")
29-
endif()
31+
CPMAddPackage(
32+
NAME Boost
33+
VERSION ${BOOST_VERSION} # Versions less than 1.85.0 may need patches for installation targets.
34+
URL https://github.com/boostorg/boost/releases/download/boost-${BOOST_VERSION}/boost-${BOOST_VERSION}-cmake.tar.xz
35+
OPTIONS "BOOST_ENABLE_CMAKE ON" "BOOST_SKIP_INSTALL_RULES ON" # Set `OFF` for installation
36+
"BUILD_SHARED_LIBS OFF" "BOOST_INCLUDE_LIBRARIES container\\\;asio\\\;format\\\;any\\\;uuid\\\;spirit\\\;serialization\\\;graph"
37+
"CMAKE_BUILD_TYPE RelWithDebInfo"
38+
)
39+
set(BOOST_LIBRARIES Boost::container Boost::asio Boost::format Boost::any Boost::uuid Boost::spirit Boost::serialization Boost::graph)
3040

31-
# Disable -Werror for CodSpeed Benchmark to avoid the unused private field error
32-
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
33-
add_compile_options(-Wno-error=unused-private-field)
34-
elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
35-
add_compile_options(-Wno-error)
36-
endif()
3741

38-
FetchContent_MakeAvailable(google_benchmark)
42+
# Create individual benchmark executables
43+
set(BENCHMARKS string_bench container_bench utility_bench optional_bench spirit_bench multiindex_bench graph_bench serialization_bench)
3944

40-
# Add Boost
41-
find_package(Boost REQUIRED
42-
COMPONENTS
43-
serialization
44-
graph
45-
)
46-
include_directories(${Boost_INCLUDE_DIRS})
45+
foreach(benchmark IN LISTS BENCHMARKS)
46+
add_executable(${benchmark} src/${benchmark}.cpp)
47+
target_link_libraries(${benchmark}
48+
benchmark::benchmark
49+
${BOOST_LIBRARIES}
50+
)
51+
endforeach()
4752

48-
# Add benchmark executable
49-
add_executable(boost_bench src/boost_bench.cpp)
50-
target_link_libraries(boost_bench
51-
benchmark::benchmark
52-
${Boost_LIBRARIES}
53+
add_custom_target(run_all_benchmarks
54+
COMMAND ${CMAKE_COMMAND} -E echo "Running all benchmarks..."
5355
)
54-
target_include_directories(boost_bench PRIVATE include)
56+
57+
# Make each benchmark depend on the run_all_benchmarks target
58+
foreach(benchmark IN LISTS BENCHMARKS)
59+
add_custom_command(
60+
TARGET run_all_benchmarks
61+
POST_BUILD
62+
COMMAND ${CMAKE_COMMAND} -E echo "Running ${benchmark}..."
63+
COMMAND $<TARGET_FILE:${benchmark}>
64+
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
65+
)
66+
endforeach()
5567

5668
# Print configuration info
5769
message(STATUS "C++ Standard: ${CMAKE_CXX_STANDARD}")
58-
message(STATUS "Boost version: ${Boost_VERSION}")
59-
message(STATUS "CodSpeed mode: ${CODSPEED_MODE}")
70+
message(STATUS "Boost version: ${BOOST_VERSION}")
71+
message(STATUS "CodSpeed mode: ${CODSPEED_MODE}")

README.md

Lines changed: 49 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
# Boost Benchmarks
22

3-
This project contains benchmarks for the Boost C++ library using Google Benchmark. It tests various components of the Boost library with different input sizes and configurations to measure performance characteristics.
3+
A benchmarking suite for comparing performance of various Boost C++ library components using Google Benchmark.
44

55
## Requirements
66

7-
- CMake (3.14 or higher)
8-
- C++ compiler with C++17 support
9-
- Boost library with the following components:
10-
- serialization
11-
- graph
12-
- Internet connection (for downloading Google Benchmark)
7+
- CMake 3.14+
8+
- C++17 compiler
9+
- Boost 1.87.0+ (with serialization and graph components)
1310

1411
## Building
1512

@@ -19,7 +16,11 @@ mkdir -p build
1916
cd build
2017

2118
# Configure and build
22-
cmake ..
19+
# For regular timing-based benchmarks:
20+
cmake -DCODSPEED_MODE=walltime ..
21+
# For CodSpeed instrumentation:
22+
cmake -DCODSPEED_MODE=instrumentation ..
23+
2324
make
2425
```
2526

@@ -28,101 +29,56 @@ make
2829
From the build directory:
2930

3031
```bash
31-
# Run all benchmarks
32-
./boost_bench
33-
34-
# Run specific benchmarks (using regex filter)
35-
./boost_bench --benchmark_filter="src/string_bench.h::BM_BoostStringSplit"
36-
37-
# List all available benchmarks
38-
./boost_bench --benchmark_list_tests
32+
# Run individual component benchmarks
33+
./string_bench
34+
./container_bench
35+
./utility_bench
36+
./optional_bench
37+
./spirit_bench
38+
./multiindex_bench
39+
./graph_bench
40+
./serialization_bench
41+
42+
# Run all benchmarks with a single command
43+
cmake --build . --target run_all_benchmarks
44+
45+
# Pass arguments to all benchmarks
46+
cmake --build . --target run_all_benchmarks -- --benchmark_filter=BM_Boost
47+
48+
# Run with regex filter
49+
./string_bench --benchmark_filter="BM_BoostLexicalCast"
50+
51+
# List available benchmarks
52+
./string_bench --benchmark_list_tests
3953
```
4054

41-
### CodSpeed Integration
55+
## Benchmark Categories
4256

43-
This project is set up to run benchmarks in CI using [CodSpeed](https://codspeed.io/). When a pull request is opened or code is pushed to the main branch, GitHub Actions will automatically build and run the benchmarks, reporting the results to CodSpeed.
57+
- **string_bench**: String operations, lexical_cast, regex, format
58+
- **container_bench**: Container performance comparisons
59+
- **utility_bench**: Type-safe any, algorithms, UUID generation
60+
- **optional_bench**: Boost vs std::optional
61+
- **spirit_bench**: Parsing operations (CSV, JSON, expressions)
62+
- **multiindex_bench**: Multi-index container operations
63+
- **graph_bench**: Graph algorithms (Dijkstra, A*, BFS, DFS)
64+
- **serialization_bench**: Serialization performance (text, binary, XML)
4465

45-
#### CI Workflow
66+
## Custom Boost Version
4667

47-
The GitHub Actions workflow:
48-
1. Installs necessary tools and dependencies:
49-
- CMake and GCC for building
50-
- Required Boost components (serialization, graph)
51-
2. Configures the project with CodSpeed instrumentation
52-
3. Builds the project
53-
4. Runs all benchmarks and reports results to CodSpeed
68+
Specify a custom Boost version:
5469

55-
#### Local CodSpeed Testing
70+
```bash
71+
cmake -DBOOST_VERSION=1.82.0 -DCODSPEED_MODE=walltime ..
72+
```
5673

57-
To enable CodSpeed instrumentation locally:
74+
## CodSpeed Integration
75+
76+
This project integrates with [CodSpeed](https://codspeed.io/) for CI performance tracking. For local testing, use:
5877

5978
```bash
60-
mkdir -p build && cd build
6179
cmake -DCODSPEED_MODE=instrumentation ..
6280
make
63-
64-
# Run the benchmarks with CodSpeed instrumentation
65-
./boost_bench
81+
./string_bench # Will show notice about running outside CI
6682
```
6783

68-
You'll see a message like this when running with CodSpeed instrumentation locally:
69-
```
70-
NOTICE: codspeed is enabled, but no performance measurement will be made since it's running in an unknown environment.
71-
```
72-
73-
This is normal as CodSpeed metrics are only collected in CI environments.
74-
75-
You'll need to set up a `CODSPEED_TOKEN` secret in your GitHub repository settings for the CodSpeed integration to work in CI.
76-
77-
## Notes
78-
79-
- CodSpeed's fork of Google Benchmark is automatically downloaded and configured via CMake's FetchContent
80-
- The benchmarks are parameterized to test with different input sizes (small, medium, large)
81-
- The project is organized into modular benchmark files for better maintainability
82-
- CodSpeed integration allows performance tracking in CI
83-
84-
## Benchmark Categories
85-
86-
### String and Text Processing
87-
- String splitting via boost::algorithm::split
88-
- Integer and floating-point conversion via boost::lexical_cast
89-
- Regular expressions via boost::regex
90-
- String formatting via boost::format
91-
92-
### Containers
93-
- Container performance comparisons:
94-
- boost::container::flat_map vs std::map
95-
- boost::container::vector vs std::vector
96-
97-
### Utility Libraries
98-
- Type-safe any type via boost::any
99-
- Algorithms: boost::algorithm::all_of
100-
- UUID generation with boost::uuid
101-
- Optional types: boost::optional vs std::optional
102-
103-
### Multi-Index Containers
104-
- Insertion performance vs standard containers
105-
- Lookup by different indices (ID, email)
106-
- Range-based queries
107-
- Modification with reindexing
108-
109-
### Spirit (Parsing)
110-
- CSV data parsing
111-
- JSON structure parsing
112-
- Calculator expression parsing
113-
114-
### Graph Algorithms
115-
- Dijkstra's shortest path algorithm
116-
- A* search on grid graphs
117-
- Breadth-First Search (BFS)
118-
- Depth-First Search (DFS)
119-
120-
### Serialization
121-
- Text archive performance
122-
- Binary archive performance
123-
- XML archive performance
124-
- Format comparison (text vs binary vs XML)
125-
126-
## Adding new benchmarks
127-
128-
Add new benchmark functions to the corresponding header file in the `src/` directory, or create a new header file for a new category of benchmarks.
84+
For CI integration, ensure the `CODSPEED_TOKEN` secret is set in your GitHub repository.

cmake/CPM.cmake

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
set(CPM_DOWNLOAD_VERSION 0.38.7)
1+
# SPDX-License-Identifier: MIT
2+
#
3+
# SPDX-FileCopyrightText: Copyright (c) 2019-2023 Lars Melchior and contributors
4+
5+
set(CPM_DOWNLOAD_VERSION 0.40.8)
6+
set(CPM_HASH_SUM "78ba32abdf798bc616bab7c73aac32a17bbd7b06ad9e26a6add69de8f3ae4791")
27

38
if(CPM_SOURCE_CACHE)
49
set(CPM_DOWNLOAD_LOCATION "${CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake")
@@ -11,22 +16,9 @@ endif()
1116
# Expand relative path. This is important if the provided path contains a tilde (~)
1217
get_filename_component(CPM_DOWNLOAD_LOCATION ${CPM_DOWNLOAD_LOCATION} ABSOLUTE)
1318

14-
function(download_cpm)
15-
message(STATUS "Downloading CPM.cmake to ${CPM_DOWNLOAD_LOCATION}")
16-
file(DOWNLOAD
17-
https://github.com/cpm-cmake/CPM.cmake/releases/download/v${CPM_DOWNLOAD_VERSION}/CPM.cmake
18-
${CPM_DOWNLOAD_LOCATION}
19-
)
20-
endfunction()
21-
22-
if(NOT EXISTS ${CPM_DOWNLOAD_LOCATION})
23-
download_cpm()
24-
else()
25-
# resume download if it previously failed
26-
file(READ ${CPM_DOWNLOAD_LOCATION} check_result LIMIT 5 OFFSET 0)
27-
if("${check_result}" STREQUAL "")
28-
download_cpm()
29-
endif()
30-
endif()
19+
file(DOWNLOAD
20+
https://github.com/cpm-cmake/CPM.cmake/releases/download/v${CPM_DOWNLOAD_VERSION}/CPM.cmake
21+
${CPM_DOWNLOAD_LOCATION} EXPECTED_HASH SHA256=${CPM_HASH_SUM}
22+
)
3123

32-
include(${CPM_DOWNLOAD_LOCATION})
24+
include(${CPM_DOWNLOAD_LOCATION})

src/boost_bench.cpp

Lines changed: 0 additions & 11 deletions
This file was deleted.
Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
#ifndef CONTAINER_BENCH_H
2-
#define CONTAINER_BENCH_H
3-
41
#include <benchmark/benchmark.h>
52
#include <boost/container/flat_map.hpp>
63
#include <boost/container/vector.hpp>
@@ -103,4 +100,4 @@ BENCHMARK(BM_BoostVector)
103100
->Arg(10000) // Medium vector
104101
->Arg(100000); // Large vector
105102

106-
#endif // CONTAINER_BENCH_H
103+
BENCHMARK_MAIN();
Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
#ifndef GRAPH_BENCH_H
2-
#define GRAPH_BENCH_H
3-
41
#include <benchmark/benchmark.h>
52
#include <boost/graph/adjacency_list.hpp>
63
#include <boost/graph/dijkstra_shortest_paths.hpp>
@@ -456,4 +453,4 @@ BENCHMARK(BM_BoostGraphDFS)
456453
->Args({1000, 10}) // Medium graph (1000 vertices, ~10 edges per vertex)
457454
->Args({5000, 20}); // Large graph (5000 vertices, ~20 edges per vertex)
458455

459-
#endif // GRAPH_BENCH_H
456+
BENCHMARK_MAIN();

0 commit comments

Comments
 (0)