|
15 | 15 | #include <iostream>
|
16 | 16 | #include <map>
|
17 | 17 | #include <string>
|
| 18 | +#include <sstream> |
18 | 19 | #include <thread>
|
19 | 20 |
|
20 | 21 | #include <cassert>
|
@@ -84,41 +85,92 @@ FATAL_BENCHMARK(group_2, benchmark_2_4) {
|
84 | 85 | }
|
85 | 86 |
|
86 | 87 | FATAL_TEST(benchmark, sanity_check) {
|
87 |
| - std::map<std::string, std::map<std::string, duration>> metrics; |
| 88 | + struct state { |
| 89 | + std::ostringstream cout; |
| 90 | + results metrics; |
| 91 | + std::thread thread; |
88 | 92 |
|
89 |
| - for (auto const &i: run(std::cout)) { |
90 |
| - auto &group = metrics[i.first]; |
| 93 | + void run_one() { |
| 94 | + metrics = run(cout); |
| 95 | + } |
| 96 | + }; |
| 97 | + auto states = std::vector<state>(12); |
91 | 98 |
|
92 |
| - for (auto const &j: i.second) { |
93 |
| - FATAL_ASSERT_EQ(group.end(), group.find(j.name())); |
| 99 | + for (auto &st : states) { |
| 100 | + st.thread = std::thread(std::bind(&state::run_one, std::ref(st))); |
| 101 | + } |
| 102 | + for (auto &st : states) { |
| 103 | + st.thread.join(); |
| 104 | + } |
94 | 105 |
|
95 |
| - group[j.name()] = j.period(); |
| 106 | + for (auto &st : states) { |
| 107 | + std::cout << st.cout.str(); |
| 108 | + |
| 109 | + for (auto const &i: st.metrics) { |
| 110 | + auto const &grp = i.second; |
| 111 | + std::vector<std::string> names; |
| 112 | + auto const txfm = std::bind(&result_entry::name, std::placeholders::_1); |
| 113 | + std::transform(grp.begin(), grp.end(), std::back_inserter(names), txfm); |
| 114 | + std::sort(names.begin(), names.end()); |
| 115 | + auto const adj = std::adjacent_find(names.begin(), names.end()); |
| 116 | + FATAL_ASSERT_EQ(adj, names.end()); |
96 | 117 | }
|
97 | 118 | }
|
98 | 119 |
|
99 |
| - auto get = [&](std::string group, std::string name) { |
100 |
| - auto i = metrics.find(group); |
101 |
| - assert(i != metrics.end()); |
| 120 | + auto get_min = [&](std::string const &group, std::string const &name) { |
| 121 | + auto min = duration{}; |
| 122 | + for (auto const &st : states) { |
| 123 | + auto const i = st.metrics.find(group); |
| 124 | + assert(i != st.metrics.end()); |
| 125 | + auto const &grp = i->second; |
| 126 | + |
| 127 | + auto const pred = [&](auto const &it) { return it.name() == name; }; |
| 128 | + auto const j = std::find_if(grp.begin(), grp.end(), pred); |
| 129 | + assert(j != i->second.end()); |
| 130 | + |
| 131 | + min = std::max(min, j->period()); |
| 132 | + } |
| 133 | + return min; |
| 134 | + }; |
| 135 | + |
| 136 | + auto get_med = [&](std::string const &group, std::string const &name) { |
| 137 | + std::vector<duration> periods; |
| 138 | + for (auto const &st : states) { |
| 139 | + auto const i = st.metrics.find(group); |
| 140 | + assert(i != st.metrics.end()); |
| 141 | + auto const &grp = i->second; |
102 | 142 |
|
103 |
| - auto j = i->second.find(name); |
104 |
| - assert(j != i->second.end()); |
| 143 | + auto const pred = [&](auto const &it) { return it.name() == name; }; |
| 144 | + auto const j = std::find_if(grp.begin(), grp.end(), pred); |
| 145 | + assert(j != i->second.end()); |
105 | 146 |
|
106 |
| - return j->second; |
| 147 | + periods.push_back(j->period()); |
| 148 | + } |
| 149 | + |
| 150 | + assert(!periods.empty()); |
| 151 | + std::sort(periods.begin(), periods.end()); |
| 152 | + if (periods.size() % 2 == 1) { |
| 153 | + return periods[periods.size() / 2]; |
| 154 | + } else { |
| 155 | + auto const m0 = periods[periods.size() / 2 - 1]; |
| 156 | + auto const m1 = periods[periods.size() / 2 - 0]; |
| 157 | + return (m0 + m1) / 2; |
| 158 | + } |
107 | 159 | };
|
108 | 160 |
|
109 | 161 | FATAL_ASSERT_LT(small_delay, big_delay);
|
110 | 162 |
|
111 |
| - FATAL_EXPECT_LT(get("group_1", "benchmark_1_1"), small_delay); |
112 |
| - FATAL_EXPECT_GE(get("group_1", "benchmark_1_2"), big_delay); |
113 |
| - FATAL_EXPECT_LT(get("group_1", "benchmark_1_3"), small_delay); |
114 |
| - FATAL_EXPECT_GE(get("group_1", "benchmark_1_4"), big_delay); |
115 |
| - FATAL_EXPECT_LT(get("group_1", "benchmark_1_5"), small_delay); |
116 |
| - |
117 |
| - FATAL_EXPECT_LT(get("group_2", "benchmark_2_1"), big_delay); |
118 |
| - FATAL_EXPECT_GE(get("group_2", "benchmark_2_1"), small_delay); |
119 |
| - FATAL_EXPECT_LT(get("group_2", "benchmark_2_2"), small_delay); |
120 |
| - FATAL_EXPECT_GE(get("group_2", "benchmark_2_3"), big_delay); |
121 |
| - FATAL_EXPECT_LT(get("group_2", "benchmark_2_4"), small_delay); |
| 163 | + FATAL_EXPECT_LT(get_med("group_1", "benchmark_1_1"), small_delay); |
| 164 | + FATAL_EXPECT_GE(get_min("group_1", "benchmark_1_2"), big_delay); |
| 165 | + FATAL_EXPECT_LT(get_med("group_1", "benchmark_1_3"), small_delay); |
| 166 | + FATAL_EXPECT_GE(get_min("group_1", "benchmark_1_4"), big_delay); |
| 167 | + FATAL_EXPECT_LT(get_med("group_1", "benchmark_1_5"), small_delay); |
| 168 | + |
| 169 | + FATAL_EXPECT_LT(get_med("group_2", "benchmark_2_1"), big_delay); |
| 170 | + FATAL_EXPECT_GE(get_min("group_2", "benchmark_2_1"), small_delay); |
| 171 | + FATAL_EXPECT_LT(get_med("group_2", "benchmark_2_2"), small_delay); |
| 172 | + FATAL_EXPECT_GE(get_min("group_2", "benchmark_2_3"), big_delay); |
| 173 | + FATAL_EXPECT_LT(get_med("group_2", "benchmark_2_4"), small_delay); |
122 | 174 | }
|
123 | 175 |
|
124 | 176 | } // namespace benchmark {
|
|
0 commit comments