1 // (See accompanying file LICENSE_1_0.txt or copy at
2 //  http://www.boost.org/LICENSE_1_0.txt)
3 
4 #include <doctest/doctest.h>
5 #include <fplus/fplus.hpp>
6 #include <fplus/stopwatch.hpp>
7 
8 using namespace std::chrono_literals;
9 
10 template<typename Function>
invoke_n_times(int n,Function f)11 auto invoke_n_times(int n, Function f)
12 {
13   for (int i = 0; i < n; i++) {
14     f();
15   }
16 }
17 
18 TEST_CASE("Timer - test_accuracy")
19 {
20 #ifdef NDEBUG  // only on release builds
21   using namespace fplus;
22   using namespace std::chrono_literals;
23 
__anonf68903720102() 24   auto measure_delta = []() {
25     fplus::stopwatch t;
26     std::this_thread::sleep_for(0.05s);
27     auto duration = t.elapsed();
28     auto delta = duration - 0.05;
29     return fabs(delta);
30   };
31 
32   // we ask for a sleep of 0.05s, but we will have a duration that can be higher
33   // (up to 15 ms higher, since the cpu scheduler might switch to another process during this sleep)
34   // to account for the cpu/task scheduler
35   double max_acceptable_delta__task_scheduler = 0.2;
36 
37   // One run
38   {
39     auto delta = measure_delta();
40     REQUIRE_LT(delta, max_acceptable_delta__task_scheduler);
41   }
42 
43   // 10 consecutive runs (total duration = 0.5 seconds)
44   {
45     std::vector<double> deltas;
__anonf68903720202() 46     invoke_n_times(10, [&]() {
47       deltas.push_back(measure_delta());
48     });
49     auto mean_dev = fplus::mean_stddev<double>(deltas);
50     REQUIRE_LT(mean_dev.first, 0.09);
51     REQUIRE_LT(mean_dev.second, 0.06);
52   }
53 #endif
54 }
55 
56