| 143 | |
| 144 | template <typename F> |
| 145 | void bench(const std::string &name, F f, int iterations = 100) { |
| 146 | stack.push_back(name); |
| 147 | if (!should_run()) { |
| 148 | stack.pop_back(); |
| 149 | return; |
| 150 | } |
| 151 | |
| 152 | ++tests; |
| 153 | out << indent() << "[bench] " << name << "\n"; |
| 154 | |
| 155 | int before_failures = failures; |
| 156 | int before_assertions = assertions; |
| 157 | |
| 158 | using clock = std::chrono::high_resolution_clock; |
| 159 | |
| 160 | std::chrono::microseconds duration(0); |
| 161 | |
| 162 | run_with_exceptions([&] { |
| 163 | for (auto i = 0; i < iterations; i++) { |
| 164 | auto start = clock::now(); |
| 165 | f(); |
| 166 | duration += std::chrono::duration_cast<std::chrono::microseconds>(clock::now() - start); |
| 167 | } |
| 168 | }, "bench"); |
| 169 | |
| 170 | auto avg_elapsed = duration.count() / iterations; |
| 171 | auto avg_elapsed_s = std::chrono::duration_cast<std::chrono::duration<double>>(duration).count() / iterations; |
| 172 | auto rate = (avg_elapsed_s > 0.0) ? (1.0 / avg_elapsed_s) : 0.0; |
| 173 | |
| 174 | int new_failures = failures - before_failures; |
| 175 | int new_assertions = assertions - before_assertions; |
| 176 | |
| 177 | std::string extra = |
| 178 | "n=" + std::to_string(iterations) + |
| 179 | " avg=" + std::to_string(avg_elapsed) + "us" + |
| 180 | " rate=" + std::to_string(int(rate)) + "/s"; |
| 181 | |
| 182 | print_result("[bench] " + name, new_failures, new_assertions, extra); |
| 183 | |
| 184 | stack.pop_back(); |
| 185 | } |
| 186 | |
| 187 | template <typename F> |
| 188 | void bench(F f, int iterations = 100) { |