Skip to content

Commit 5cd95de

Browse files
committed
add benchmarks
1 parent 7ba1f2e commit 5cd95de

File tree

7 files changed

+342
-51
lines changed

7 files changed

+342
-51
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,5 @@ out/
1010
build/*
1111
!build/*.sh
1212
*.exe
13+
14+
.cache/

CMakeLists.txt

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,23 @@ include(GNUInstallDirs)
66
include(CMakePackageConfigHelpers)
77

88
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/build")
9+
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
910

1011
if(NOT CMAKE_BUILD_TYPE MATCHES "^(Debug|Release|RelWithDebInfo)$")
1112
message(WARNING "The specified build type [${CMAKE_BUILD_TYPE}] is not recognized. Defaulting to Release.")
1213
set(CMAKE_BUILD_TYPE "Release")
1314
endif()
1415

1516
if(MSVC)
16-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -permissive- -W4 -WX -wd4324 -diagnostics:caret")
17+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -permissive- -W4 -WX -wd4324 -diagnostics:caret -Z7")
1718
else()
1819
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wpedantic -Werror -pedantic-errors -g")
20+
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3")
1921
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
2022
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-maybe-uninitialized")
2123
endif()
2224
endif()
2325

24-
if(CMAKE_BUILD_TYPE MATCHES "(Release|RelWithDebInfo)")
25-
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
26-
endif()
27-
2826
add_library(small_unique_ptr INTERFACE)
2927
target_include_directories(small_unique_ptr SYSTEM INTERFACE "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>"
3028
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>")
@@ -51,3 +49,4 @@ include(CTest)
5149

5250
enable_testing()
5351
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/test")
52+
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/benchmark")

benchmark/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
find_package(benchmark REQUIRED)
2+
3+
add_executable(small_unique_ptr_benchmark "${CMAKE_CURRENT_SOURCE_DIR}/small_unique_ptr.cpp")
4+
target_link_libraries(small_unique_ptr_benchmark PRIVATE small_unique_ptr benchmark::benchmark_main)

benchmark/small_unique_ptr.cpp

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
#include <small_unique_ptr.hpp>
2+
#include <benchmark/benchmark.h>
3+
#include <memory>
4+
5+
6+
struct Base { virtual ~Base() = default; };
7+
8+
struct SmallDerived : public Base
9+
{
10+
int n_;
11+
};
12+
13+
struct LargeDerived : public Base
14+
{
15+
int n_[16];
16+
};
17+
18+
/* --------------------------------------------------------------------------------------------- */
19+
20+
template<typename T>
21+
void bm_make_unique(benchmark::State& state)
22+
{
23+
for (auto _ : state)
24+
{
25+
std::unique_ptr<Base> ptr = std::make_unique<T>();
26+
benchmark::DoNotOptimize(ptr);
27+
}
28+
}
29+
30+
31+
template<typename T>
32+
void bm_make_unique_small(benchmark::State& state)
33+
{
34+
for (auto _ : state)
35+
{
36+
smp::small_unique_ptr<Base> ptr = smp::make_unique_small<T, Base>();
37+
benchmark::DoNotOptimize(ptr);
38+
}
39+
}
40+
41+
template<typename T>
42+
void bm_make_unique_small_cast(benchmark::State& state)
43+
{
44+
for (auto _ : state)
45+
{
46+
smp::small_unique_ptr<Base> ptr = smp::make_unique_small<T>();
47+
benchmark::DoNotOptimize(ptr);
48+
}
49+
}
50+
51+
BENCHMARK(bm_make_unique<SmallDerived>);
52+
BENCHMARK(bm_make_unique_small<SmallDerived>);
53+
BENCHMARK(bm_make_unique_small_cast<SmallDerived>);
54+
55+
BENCHMARK(bm_make_unique<LargeDerived>);
56+
BENCHMARK(bm_make_unique_small<LargeDerived>);
57+
BENCHMARK(bm_make_unique_small_cast<LargeDerived>);
58+
59+
/* --------------------------------------------------------------------------------------------- */
60+
61+
template<typename T>
62+
void bm_move_construct2_unique_ptr(benchmark::State& state)
63+
{
64+
std::unique_ptr<Base> p1 = std::make_unique<T>();
65+
std::unique_ptr<Base> p2;
66+
67+
for (auto _ : state)
68+
{
69+
std::construct_at(&p2, std::move(p1));
70+
std::destroy_at(&p1);
71+
72+
benchmark::DoNotOptimize(p1);
73+
benchmark::DoNotOptimize(p2);
74+
75+
std::construct_at(&p1, std::move(p2));
76+
std::destroy_at(&p2);
77+
78+
benchmark::DoNotOptimize(p1);
79+
benchmark::DoNotOptimize(p2);
80+
}
81+
}
82+
83+
template<typename T>
84+
void bm_move_construct2_small_unique_ptr(benchmark::State& state)
85+
{
86+
smp::small_unique_ptr<Base> p1 = smp::make_unique_small<T>();
87+
smp::small_unique_ptr<Base> p2;
88+
89+
for (auto _ : state)
90+
{
91+
std::construct_at(&p2, std::move(p1));
92+
std::destroy_at(&p1);
93+
94+
benchmark::DoNotOptimize(p1);
95+
benchmark::DoNotOptimize(p2);
96+
97+
std::construct_at(&p1, std::move(p2));
98+
std::destroy_at(&p2);
99+
100+
benchmark::DoNotOptimize(p1);
101+
benchmark::DoNotOptimize(p2);
102+
}
103+
}
104+
105+
BENCHMARK(bm_move_construct2_unique_ptr<SmallDerived>);
106+
BENCHMARK(bm_move_construct2_unique_ptr<LargeDerived>);
107+
108+
BENCHMARK(bm_move_construct2_small_unique_ptr<SmallDerived>);
109+
BENCHMARK(bm_move_construct2_small_unique_ptr<LargeDerived>);
110+
111+
/* --------------------------------------------------------------------------------------------- */
112+
113+
template<typename T>
114+
void bm_move_assign2_unique_ptr(benchmark::State& state)
115+
{
116+
std::unique_ptr<Base> left = std::make_unique<T>();
117+
std::unique_ptr<Base> right = std::make_unique<T>();
118+
119+
for (auto _ : state)
120+
{
121+
right = std::move(left);
122+
123+
benchmark::DoNotOptimize(left);
124+
benchmark::DoNotOptimize(right);
125+
126+
left = std::move(right);
127+
128+
benchmark::DoNotOptimize(left);
129+
benchmark::DoNotOptimize(right);
130+
}
131+
}
132+
133+
template<typename T>
134+
void bm_move_assign2_small_unique_ptr(benchmark::State& state)
135+
{
136+
smp::small_unique_ptr<Base> left = smp::make_unique_small<T>();
137+
smp::small_unique_ptr<Base> right = smp::make_unique_small<T>();
138+
139+
for (auto _ : state)
140+
{
141+
right = std::move(left);
142+
143+
benchmark::DoNotOptimize(left);
144+
benchmark::DoNotOptimize(right);
145+
146+
left = std::move(right);
147+
148+
benchmark::DoNotOptimize(left);
149+
benchmark::DoNotOptimize(right);
150+
}
151+
}
152+
153+
BENCHMARK(bm_move_assign2_unique_ptr<SmallDerived>);
154+
BENCHMARK(bm_move_assign2_unique_ptr<LargeDerived>);
155+
156+
BENCHMARK(bm_move_assign2_small_unique_ptr<SmallDerived>);
157+
BENCHMARK(bm_move_assign2_small_unique_ptr<LargeDerived>);
158+
159+
/* --------------------------------------------------------------------------------------------- */
160+
161+
template<typename T>
162+
void bm_swap_unique_ptr(benchmark::State& state)
163+
{
164+
std::unique_ptr<T> lhs = std::make_unique<T>();
165+
std::unique_ptr<T> rhs = std::make_unique<T>();
166+
167+
for (auto _ : state)
168+
{
169+
benchmark::DoNotOptimize(lhs);
170+
benchmark::DoNotOptimize(rhs);
171+
172+
using std::swap;
173+
swap(lhs, rhs);
174+
}
175+
}
176+
177+
178+
template<typename T, typename U = T>
179+
void bm_swap_small_unique_ptr(benchmark::State& state)
180+
{
181+
smp::small_unique_ptr<Base> lhs = smp::make_unique_small<T>();
182+
smp::small_unique_ptr<Base> rhs = smp::make_unique_small<U>();
183+
184+
for (auto _ : state)
185+
{
186+
benchmark::DoNotOptimize(lhs);
187+
benchmark::DoNotOptimize(rhs);
188+
189+
using std::swap;
190+
swap(lhs, rhs);
191+
}
192+
}
193+
194+
BENCHMARK(bm_swap_unique_ptr<SmallDerived>);
195+
BENCHMARK(bm_swap_unique_ptr<LargeDerived>);
196+
197+
BENCHMARK(bm_swap_small_unique_ptr<SmallDerived, SmallDerived>);
198+
BENCHMARK(bm_swap_small_unique_ptr<LargeDerived, LargeDerived>);
199+
BENCHMARK(bm_swap_small_unique_ptr<SmallDerived, LargeDerived>);
200+
201+
/* --------------------------------------------------------------------------------------------- */

build/install_catch.sh

Lines changed: 0 additions & 27 deletions
This file was deleted.

0 commit comments

Comments
 (0)