Skip to content

Commit d5065cf

Browse files
committed
feat: Add ScopedPauseTiming RAII helper
Adds a new `benchmark::ScopedPauseTiming` class that provides a convenient RAII-style mechanism for pausing and resuming benchmark timers. This is less error-prone than manually calling `PauseTiming` and `ResumeTiming`, as it guarantees that the timer is resumed when the scope is exited. - Added `ScopedPauseTiming` to `include/benchmark/state.h`. - Added a new test `test/scoped_pause_test.cc` to verify the functionality and prevent regressions. - Updated `test/CMakeLists.txt` to include the new test. - Added documentation for the new feature in `docs/user_guide.md`.
1 parent 8dc85ae commit d5065cf

File tree

4 files changed

+68
-0
lines changed

4 files changed

+68
-0
lines changed

docs/user_guide.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1066,6 +1066,29 @@ BENCHMARK(BM_SetInsert_With_Timer_Control)->Ranges({{1<<10, 8<<10}, {128, 512}})
10661066
```
10671067
<!-- {% endraw %} -->
10681068
1069+
For convenience, a `ScopedPauseTiming` class is provided to manage pausing and
1070+
resuming timers within a scope. This is less error-prone than manually calling
1071+
`PauseTiming` and `ResumeTiming`.
1072+
1073+
<!-- {% raw %} -->
1074+
```c++
1075+
static void BM_SetInsert_With_Scoped_Timer_Control(benchmark::State& state) {
1076+
std::set<int> data;
1077+
for (auto _ : state) {
1078+
{
1079+
benchmark::ScopedPauseTiming pause(state); // Pauses timing
1080+
data = ConstructRandomSet(state.range(0));
1081+
} // Timing resumes automatically when 'pause' goes out of scope
1082+
1083+
// The rest will be measured.
1084+
for (int j = 0; j < state.range(1); ++j)
1085+
data.insert(RandomNumber());
1086+
}
1087+
}
1088+
BENCHMARK(BM_SetInsert_With_Scoped_Timer_Control)->Ranges({{1<<10, 8<<10}, {128, 512}});
1089+
```
1090+
<!-- {% endraw %} -->
1091+
10691092
<a name="manual-timing" />
10701093

10711094
## Manual Timing

include/benchmark/state.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,19 @@ inline BENCHMARK_ALWAYS_INLINE State::StateIterator State::end() {
256256
return StateIterator();
257257
}
258258

259+
class ScopedPauseTiming {
260+
public:
261+
explicit ScopedPauseTiming(State& state) : state_(state) {
262+
state_.PauseTiming();
263+
}
264+
~ScopedPauseTiming() { state_.ResumeTiming(); }
265+
266+
private:
267+
ScopedPauseTiming(const ScopedPauseTiming&) = delete;
268+
void operator=(const ScopedPauseTiming&) = delete;
269+
State& state_;
270+
};
271+
259272
} // namespace benchmark
260273

261274
#if defined(_MSC_VER)

test/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,9 @@ benchmark_add_test(NAME complexity_benchmark COMMAND complexity_test --benchmark
225225
compile_output_test(locale_impermeability_test)
226226
benchmark_add_test(NAME locale_impermeability_test COMMAND locale_impermeability_test)
227227

228+
compile_output_test(scoped_pause_test)
229+
benchmark_add_test(NAME scoped_pause_test COMMAND scoped_pause_test)
230+
228231
###############################################################################
229232
# GoogleTest Unit Tests
230233
###############################################################################

test/scoped_pause_test.cc

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
2+
#include <chrono>
3+
#include <thread>
4+
5+
#include "benchmark/benchmark.h"
6+
#include "output_test.h"
7+
8+
// BM_ScopedPause sleeps for 10ms in a ScopedPauseTiming block.
9+
// The reported time should be much less than 10ms.
10+
void BM_ScopedPause(benchmark::State& state) {
11+
for (auto _ : state) {
12+
benchmark::ScopedPauseTiming pause(state);
13+
std::this_thread::sleep_for(std::chrono::milliseconds(10));
14+
}
15+
}
16+
BENCHMARK(BM_ScopedPause)->UseRealTime()->Iterations(1);
17+
18+
void CheckResults(Results const& results) {
19+
// Check that the real time is much less than the 10ms sleep time.
20+
// Allow for up to 1ms of timing noise/overhead.
21+
CHECK_FLOAT_RESULT_VALUE(results, "real_time", LT, 1e6, 0.0);
22+
}
23+
CHECK_BENCHMARK_RESULTS("BM_ScopedPause", &CheckResults);
24+
25+
int main(int argc, char* argv[]) {
26+
benchmark::MaybeReenterWithoutASLR(argc, argv);
27+
RunOutputTests(argc, argv);
28+
return 0;
29+
}

0 commit comments

Comments
 (0)