|
| | Bench () |
| | Creates a new benchmark for configuration and running of benchmarks. More...
|
| |
| | Bench (Bench &&other) |
| |
| Bench & | operator= (Bench &&other) |
| |
| | Bench (Bench const &other) |
| |
| Bench & | operator= (Bench const &other) |
| |
| | ~Bench () noexcept |
| |
| template<typename Op > |
| Bench & | run (char const *benchmarkName, Op &&op) |
| | Repeatedly calls op() based on the configuration, and performs measurements. More...
|
| |
| template<typename Op > |
| Bench & | run (std::string const &benchmarkName, Op &&op) |
| |
| template<typename Op > |
| Bench & | run (Op &&op) |
| | Same as run(char const* benchmarkName, Op op), but instead uses the previously set name. More...
|
| |
| Bench & | title (char const *benchmarkTitle) |
| | Title of the benchmark, will be shown in the table header. More...
|
| |
| Bench & | title (std::string const &benchmarkTitle) |
| |
ANKERL_NANOBENCH(NODISCARD)
std Bench & | name (char const *benchmarkName) |
| | Name of the benchmark, will be shown in the table row. More...
|
| |
| Bench & | name (std::string const &benchmarkName) |
| |
| template<typename T > |
ANKERL_NANOBENCH(NODISCARD)
std Bench & | batch (T b) noexcept |
| | Sets the batch size. More...
|
| |
| | ANKERL_NANOBENCH (NODISCARD) double batch() const noexcept |
| |
| Bench & | unit (char const *unit) |
| | Sets the operation unit. More...
|
| |
| Bench & | unit (std::string const &unit) |
| |
ANKERL_NANOBENCH(NODISCARD)
std Bench & | output (std::ostream *outstream) noexcept |
| | Set the output stream where the resulting markdown table will be printed to. More...
|
| |
ANKERL_NANOBENCH(NODISCARD)
std Bench & | clockResolutionMultiple (size_t multiple) noexcept |
| | Modern processors have a very accurate clock, being able to measure as low as 20 nanoseconds. More...
|
| |
| | ANKERL_NANOBENCH (NODISCARD) size_t clockResolutionMultiple() const noexcept |
| |
| Bench & | epochs (size_t numEpochs) noexcept |
| | Controls number of epochs, the number of measurements to perform. More...
|
| |
| | ANKERL_NANOBENCH (NODISCARD) size_t epochs() const noexcept |
| |
| Bench & | maxEpochTime (std::chrono::nanoseconds t) noexcept |
| | Upper limit for the runtime of each epoch. More...
|
| |
ANKERL_NANOBENCH(NODISCARD)
std Bench & | minEpochTime (std::chrono::nanoseconds t) noexcept |
| | Minimum time each epoch should take. More...
|
| |
ANKERL_NANOBENCH(NODISCARD)
std Bench & | minEpochIterations (uint64_t numIters) noexcept |
| | Sets the minimum number of iterations each epoch should take. More...
|
| |
| | ANKERL_NANOBENCH (NODISCARD) uint64_t minEpochIterations() const noexcept |
| |
| Bench & | epochIterations (uint64_t numIters) noexcept |
| | Sets exactly the number of iterations for each epoch. More...
|
| |
| | ANKERL_NANOBENCH (NODISCARD) uint64_t epochIterations() const noexcept |
| |
| Bench & | warmup (uint64_t numWarmupIters) noexcept |
| | Sets a number of iterations that are initially performed without any measurements. More...
|
| |
| | ANKERL_NANOBENCH (NODISCARD) uint64_t warmup() const noexcept |
| |
| Bench & | relative (bool isRelativeEnabled) noexcept |
| | Marks the next run as the baseline. More...
|
| |
| | ANKERL_NANOBENCH (NODISCARD) bool relative() const noexcept |
| |
| Bench & | performanceCounters (bool showPerformanceCounters) noexcept |
| | Enables/disables performance counters. More...
|
| |
| | ANKERL_NANOBENCH (NODISCARD) bool performanceCounters() const noexcept |
| |
| template<typename Arg > |
ANKERL_NANOBENCH(NODISCARD)
std Bench & | doNotOptimizeAway (Arg &&arg) |
| | Retrieves all benchmark results collected by the bench object so far. More...
|
| |
| template<typename T > |
| Bench & | complexityN (T b) noexcept |
| |
| | ANKERL_NANOBENCH (NODISCARD) double complexityN() const noexcept |
| |
| std::vector< BigO > | complexityBigO () const |
| |
| template<typename Op > |
| BigO | complexityBigO (char const *name, Op op) const |
| | Calculates bigO for a custom function. More...
|
| |
| template<typename Op > |
| BigO | complexityBigO (std::string const &name, Op op) const |
| |
| Bench & | render (char const *templateContent, std::ostream &os) |
| |
| Bench & | config (Config const &benchmarkConfig) |
| |
| | ANKERL_NANOBENCH (NODISCARD) Config const &config() const noexcept |
| |
| template<typename T > |
| Bench & | batch (T b) noexcept |
| |
| template<typename Arg > |
| Bench & | doNotOptimizeAway (Arg &&arg) |
| |
Main entry point to nanobench's benchmarking facility.
It holds configuration and results from one or more benchmark runs. Usually it is used in a single line, where the object is constructed, configured, and then a benchmark is run. E.g. like this:
ankerl::nanobench::Bench().unit("byte").batch(1000).run("random fluctuations", [&] {
// here be the benchmark code
});
In that example Bench() constructs the benchmark, it is then configured with unit() and batch(), and after configuration a benchmark is executed with run(). Once run() has finished, it prints the result to std::cout. It would also store the results in the Bench instance, but in this case the object is immediately destroyed so it's not available any more.
Definition at line 583 of file nanobench.h.
Modern processors have a very accurate clock, being able to measure as low as 20 nanoseconds.
This is the main trick nanobech to be so fast: we find out how accurate the clock is, then run the benchmark only so often that the clock's accuracy is good enough for accurate measurements.
The default is to run one epoch for 1000 times the clock resolution. So for 20ns resolution and 11 epochs, this gives a total runtime of
To be precise, nanobench adds a 0-20% random noise to each evaluation. This is to prevent any aliasing effects, and further improves accuracy.
Total runtime will be higher though: Some initial time is needed to find out the target number of iterations for each epoch, and there is some overhead involved to start & stop timers and calculate resulting statistics and writing the output.
- Parameters
-
| multiple | Target number of times of clock resolution. Usually 1000 is a good compromise between runtime and accuracy. |
template<typename Op >
| BigO ankerl::nanobench::Bench::complexityBigO |
( |
char const * |
name, |
|
|
Op |
op |
|
) |
| const |
Calculates bigO for a custom function.
E.g. to calculate the mean squared error for
, which is not part of the default set of complexityBigO(), you can do this:
``` auto logLogN = bench.complexityBigO("O(log log n)", [](double n) { return std::log2(std::log2(n)); }); ```
The resulting mean squared error can be printed with std::cout << logLogN. E.g. it prints something like this:
```text 2.46985e-05 * O(log log n), rms=1.48121 ```
- Template Parameters
-
| Op | Type of mapping operation. |
- Parameters
-
| name | Name for the function, e.g. "O(log log n)" |
| op | Op's operator() maps a double with the desired complexity function, e.g. log2(log2(n)). |
- Returns
- BigO Error calculation, which is streamable to std::cout.
Definition at line 1146 of file nanobench.h.
| Bench& ankerl::nanobench::Bench::epochs |
( |
size_t |
numEpochs | ) |
|
|
noexcept |
Controls number of epochs, the number of measurements to perform.
The reported result will be the median of evaluation of each epoch. The higher you choose this, the more deterministic the result be and outliers will be more easily removed. Also the err% will be more accurate the higher this number is. Note that the err% will not necessarily decrease when number of epochs is increased. But it will be a more accurate representation of the benchmarked code's runtime stability.
Choose the value wisely. In practice, 11 has been shown to be a reasonable choice between runtime performance and accuracy. This setting goes hand in hand with minEpocIterations() (or minEpochTime()). If you are more interested in median runtime, you might want to increase epochs(). If you are more interested in mean runtime, you might want to increase minEpochIterations() instead.
- Parameters
-
| numEpochs | Number of epochs. |
template<typename Op >
| Bench & ankerl::nanobench::Bench::run |
( |
char const * |
benchmarkName, |
|
|
Op && |
op |
|
) |
| |
Repeatedly calls op() based on the configuration, and performs measurements.
This call is marked with noinline to prevent the compiler to optimize beyond different benchmarks. This can have quite a big effect on benchmark accuracy.
embed:rst
.. note::
Each call to your lambda must have a side effect that the compiler can't possibly optimize it away. E.g. add a result to an
externally defined number (like `x` in the above example), and finally call `doNotOptimizeAway` on the variables the compiler
must not remove. You can also use :cpp:func:`ankerl::nanobench::doNotOptimizeAway` directly in the lambda, but be aware that
this has a small overhead.
- Template Parameters
-
Definition at line 1134 of file nanobench.h.