|
| 1 | +//===----------------------------------------------------------------------===// |
| 2 | +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 3 | +// See https://llvm.org/LICENSE.txt for license information. |
| 4 | +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 5 | +// |
| 6 | +//===----------------------------------------------------------------------===// |
| 7 | + |
| 8 | +// REQUIRES: std-at-least-c++23 |
| 9 | + |
| 10 | +// This benchmark writes the print and benchmark data to stdout. In order to |
| 11 | +// preserve the benchmark output it needs to be stored in a file (using the |
| 12 | +// console format). Another issue with the benchmark is the time it takes to |
| 13 | +// write output to the real terminal. In order to avoid that overhead write the |
| 14 | +// output to a fast "terminal", like /dev/null. For example, the printf |
| 15 | +// console 1546 ns |
| 16 | +// /dev/null 70.9 ns |
| 17 | +// An example of a good test invocation. |
| 18 | +// BENCHMARK_OUT=benchmark.txt BENCHMARK_OUT_FORMAT=console <exe> >/dev/null |
| 19 | + |
| 20 | +#include <print> |
| 21 | + |
| 22 | +#include <cstdio> |
| 23 | +#include <string> |
| 24 | +#include <vector> |
| 25 | + |
| 26 | +#include "benchmark/benchmark.h" |
| 27 | + |
| 28 | +void printf(benchmark::State& s) { |
| 29 | + while (s.KeepRunning()) |
| 30 | + std::printf("The answer to life, the universe, and everything is %d.\n", 42); |
| 31 | +} |
| 32 | +BENCHMARK(printf); |
| 33 | + |
| 34 | +void vprint_string(std::string_view fmt, std::format_args args) { |
| 35 | + auto s = std::vformat(fmt, args); |
| 36 | + std::size_t result = fwrite(s.data(), 1, s.size(), stdout); |
| 37 | + if (result < s.size()) |
| 38 | + throw std::format_error("fwrite error"); |
| 39 | +} |
| 40 | + |
| 41 | +template <typename... T> |
| 42 | +void print_string(std::format_string<T...> fmt, T&&... args) { |
| 43 | + vprint_string(fmt.get(), std::make_format_args(args...)); |
| 44 | +} |
| 45 | + |
| 46 | +void print_string(benchmark::State& s) { |
| 47 | + while (s.KeepRunning()) { |
| 48 | + print_string("The answer to life, the universe, and everything is {}.\n", 42); |
| 49 | + } |
| 50 | +} |
| 51 | +BENCHMARK(print_string); |
| 52 | + |
| 53 | +void vprint_stack(std::string_view fmt, std::format_args args) { |
| 54 | + auto buf = std::vector<char>{}; |
| 55 | + std::vformat_to(std::back_inserter(buf), fmt, args); |
| 56 | + std::size_t result = fwrite(buf.data(), 1, buf.size(), stdout); |
| 57 | + if (result < buf.size()) |
| 58 | + throw std::format_error("fwrite error"); |
| 59 | +} |
| 60 | + |
| 61 | +template <typename... T> |
| 62 | +void print_stack(std::format_string<T...> fmt, T&&... args) { |
| 63 | + vprint_stack(fmt.get(), std::make_format_args(args...)); |
| 64 | +} |
| 65 | + |
| 66 | +void print_stack(benchmark::State& s) { |
| 67 | + while (s.KeepRunning()) { |
| 68 | + print_stack("The answer to life, the universe, and everything is {}.\n", 42); |
| 69 | + } |
| 70 | +} |
| 71 | +BENCHMARK(print_stack); |
| 72 | + |
| 73 | +void print_direct(benchmark::State& s) { |
| 74 | + while (s.KeepRunning()) |
| 75 | + std::print("The answer to life, the universe, and everything is {}.\n", 42); |
| 76 | +} |
| 77 | +BENCHMARK(print_direct); |
| 78 | + |
| 79 | +BENCHMARK_MAIN(); |
0 commit comments