forked from apolukhin/course-nimble_cpp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
container_7.hpp
112 lines (84 loc) · 3.19 KB
/
container_7.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include "util.hpp"
#include <vector>
#include <string>
//////////////////////////// TASK 7 ////////////////////////////
using vs_type = std::vector<std::string>; // Do not modify
const std::string s_base {
"A variable x whose name appears as a potentially-evaluated expression ex is odr-used by ex unless applying "
"the lvalue-to-rvalue conversion (7.1) to x yields a constant expression (8.6) that does not invoke any non-trivial "
"functions and, if x is an object, ex is an element of the set of potential results of an expression e, where "
"either the lvalue-to-rvalue conversion (7.1) is applied to e, or e is a discarded-value expression (8.2)."
""
"A structured binding is odr-used if it appears as a potentially-evaluated expression."
};
// Do not change
static vs_type generate_naive(std::size_t elements_count) {
vs_type v;
for (unsigned i = 0; i < elements_count; ++i) {
std::string s {s_base};
s += static_cast<char>(elements_count % 256);
elements_count >>= 1;
s += static_cast<char>(elements_count % 256);
v.push_back(s);
}
return v;
}
static vs_type filter_naive(vs_type generated) {
vs_type dest;
dest.resize(generated.size());
const auto it = std::copy_if(
generated.begin(),
generated.end(),
dest.begin(),
[](const std::string& v) { return std::hash<std::string>{}(v) & 1; }
);
dest.erase(it, dest.end());
return dest;
}
static vs_type generate_filter_naive(std::size_t elements_count) {
return filter_naive(generate_naive(elements_count));
}
static vs_type generate_optim(std::size_t elements_count) {
vs_type v;
for (unsigned i = 0; i < elements_count; ++i) {
std::string s {s_base};
s += static_cast<char>(elements_count % 256);
elements_count >>= 1;
s += static_cast<char>(elements_count % 256);
v.push_back(s);
}
return v;
}
static vs_type filter_optim(vs_type generated) {
vs_type dest;
dest.resize(generated.size());
const auto it = std::copy_if(
generated.begin(),
generated.end(),
dest.begin(),
[](const std::string& v) { return std::hash<std::string>{}(v) & 1; }
);
dest.erase(it, dest.end());
return dest;
}
static vs_type generate_filter_optim(std::size_t elements_count) {
return filter_optim(generate_optim(elements_count));
}
//////////////////////////// DETAIL ////////////////////////////
template <class Generator>
static void mesure_generate_and_filter(benchmark::State& state, Generator generator) {
const std::size_t elements_count = state.range(0);
for (auto _ : state) {
vs_type dest = generator(elements_count);
state.PauseTiming();
if (generator != generate_filter_naive) {
if (dest != generate_filter_naive(elements_count)) {
throw std::runtime_error("values missmatch");
}
}
state.ResumeTiming();
benchmark::DoNotOptimize(dest);
}
}
BENCH(mesure_generate_and_filter, generate_and_filter_naive, &generate_filter_naive)->Range(8, 8<<10);
BENCH(mesure_generate_and_filter, generate_and_filter_optim, &generate_filter_optim)->Range(8, 8<<10);