|
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