@@ -10,25 +10,41 @@ std::default_random_engine gen;
10
10
std::uniform_int_distribution<Id> sensor_id_gen (0 , 100 );
11
11
std::uniform_int_distribution<Id> object_id_gen (0 , 10 );
12
12
std::uniform_real_distribution<double > real_gen (-10.0 , 10.0 );
13
+ std::uniform_int_distribution<int > char_gen (' a' , ' z' );
13
14
14
- struct SensorData {
15
+
16
+ struct ArraySensorData {
15
17
std::array<double , 18 > xyz;
16
18
17
- static SensorData random () {
18
- SensorData s;
19
+ static ArraySensorData random () {
20
+ ArraySensorData s;
19
21
for (size_t i = 0 ; i < s.xyz .size (); ++i) {
20
22
s.xyz [i] = real_gen (gen);
21
23
}
22
24
return s;
23
25
};
24
26
};
25
27
26
- template <typename ... Ts>
27
- std::ostream& operator <<(std::ostream& cout, const SensorData& s) {
28
- cout << " {" << s.xyz [0 ] << " , " << s.xyz [1 ] << " , " << s.xyz [2 ] << " }" ;
29
- return cout;
30
- }
28
+ struct StringSensorData {
29
+ // contribution from greg7mdp during code review
30
+ // for testing string data
31
+ // https://github.com/markisus/vapid-soa/pull/3#issuecomment-1035390996
32
+
33
+ std::string data;
34
+
35
+ static StringSensorData random () {
36
+ StringSensorData res;
37
+ char buff[31 ];
38
+ for (size_t i = 0 ; i < 30 ; ++i) {
39
+ buff[i] = char_gen (gen);
40
+ }
41
+ buff[30 ] = 0 ;
42
+ res.data = buff;
43
+ return res;
44
+ };
45
+ };
31
46
47
+ template <typename SensorData>
32
48
struct Measurement {
33
49
Id sensor_id;
34
50
Id object_id;
@@ -45,20 +61,15 @@ struct Measurement {
45
61
}
46
62
};
47
63
48
- template <typename ... Ts>
49
- std::ostream& operator <<(std::ostream& cout, const Measurement& m) {
50
- cout << " Measurement{" << m.sensor_id << " , " << m.object_id << " , " << m.timestamp << " , " << m.data << " }" ;
51
- return cout;
52
- }
53
-
64
+ template <typename SensorData>
54
65
struct TestCase {
55
66
vapid::soa<Id, Id, double , SensorData> measurements_soa;
56
- std::vector<Measurement> measurements_vec;
67
+ std::vector<Measurement<SensorData> > measurements_vec;
57
68
58
69
static TestCase random () {
59
70
TestCase t;
60
71
for (int i = 0 ; i < 100000 ; ++i) {
61
- Measurement m = Measurement::random ();
72
+ Measurement<SensorData> m = Measurement<SensorData> ::random ();
62
73
t.measurements_vec .push_back (m);
63
74
t.measurements_soa .insert (m.sensor_id , m.object_id , m.timestamp , m.data );
64
75
}
@@ -67,23 +78,35 @@ struct TestCase {
67
78
}
68
79
};
69
80
70
- const TestCase random_data = TestCase::random();
81
+ const auto random_array_data = TestCase<ArraySensorData>::random();
82
+ const auto random_string_data = TestCase<StringSensorData>::random();
83
+
84
+ static void BM_SoaSortBySensorId_ArrayData (benchmark::State& state) {
85
+ for (auto _ : state) {
86
+ state.PauseTiming ();
87
+ auto soa = random_array_data.measurements_soa ;
88
+ state.ResumeTiming ();
89
+
90
+ soa.sort_by_field <0 >();
91
+ benchmark::DoNotOptimize (soa.get_column <0 >()[0 ]);
92
+ }
93
+ }
71
94
72
- static void BM_SoaSortBySensorId (benchmark::State& state) {
95
+ static void BM_SoaSortBySensorId_StringData (benchmark::State& state) {
73
96
for (auto _ : state) {
74
97
state.PauseTiming ();
75
- auto soa = random_data .measurements_soa ;
98
+ auto soa = random_string_data .measurements_soa ;
76
99
state.ResumeTiming ();
77
100
78
101
soa.sort_by_field <0 >();
79
102
benchmark::DoNotOptimize (soa.get_column <0 >()[0 ]);
80
103
}
81
104
}
82
105
83
- static void BM_VecSortBySensorId (benchmark::State& state) {
106
+ static void BM_VecSortBySensorId_ArrayData (benchmark::State& state) {
84
107
for (auto _ : state) {
85
108
state.PauseTiming ();
86
- auto vec = random_data .measurements_vec ;
109
+ auto vec = random_array_data .measurements_vec ;
87
110
state.ResumeTiming ();
88
111
89
112
std::stable_sort (vec.begin (),
@@ -95,8 +118,23 @@ static void BM_VecSortBySensorId(benchmark::State& state) {
95
118
}
96
119
}
97
120
98
- static void BM_SoaSumTimestamps (benchmark::State& state) {
99
- const auto & soa = random_data.measurements_soa ;
121
+ static void BM_VecSortBySensorId_StringData (benchmark::State& state) {
122
+ for (auto _ : state) {
123
+ state.PauseTiming ();
124
+ auto vec = random_string_data.measurements_vec ;
125
+ state.ResumeTiming ();
126
+
127
+ std::stable_sort (vec.begin (),
128
+ vec.end (),
129
+ [](auto & m1, auto & m2) {
130
+ return m1.sensor_id < m2.sensor_id ;
131
+ });
132
+ benchmark::DoNotOptimize (vec[0 ]);
133
+ }
134
+ }
135
+
136
+ static void BM_SoaSumTimestamps_ArrayData (benchmark::State& state) {
137
+ const auto & soa = random_array_data.measurements_soa ;
100
138
for (auto _ : state) {
101
139
double sum = 0 ;
102
140
for (double d : soa.get_column <2 >()) {
@@ -106,8 +144,8 @@ static void BM_SoaSumTimestamps(benchmark::State& state) {
106
144
}
107
145
}
108
146
109
- static void BM_VecSumTimestamps (benchmark::State& state) {
110
- const auto & vec = random_data .measurements_vec ;
147
+ static void BM_VecSumTimestamps_ArrayData (benchmark::State& state) {
148
+ const auto & vec = random_array_data .measurements_vec ;
111
149
for (auto _ : state) {
112
150
double sum = 0 ;
113
151
for (const auto & meas : vec) {
@@ -119,9 +157,12 @@ static void BM_VecSumTimestamps(benchmark::State& state) {
119
157
120
158
121
159
// Register the function as a benchmark
122
- BENCHMARK (BM_SoaSortBySensorId);
123
- BENCHMARK (BM_VecSortBySensorId);
124
- BENCHMARK (BM_SoaSumTimestamps);
125
- BENCHMARK (BM_VecSumTimestamps);
160
+ BENCHMARK (BM_SoaSortBySensorId_ArrayData);
161
+ BENCHMARK (BM_VecSortBySensorId_ArrayData);
162
+ BENCHMARK (BM_SoaSortBySensorId_StringData);
163
+ BENCHMARK (BM_VecSortBySensorId_StringData);
164
+
165
+ BENCHMARK (BM_SoaSumTimestamps_ArrayData);
166
+ BENCHMARK (BM_VecSumTimestamps_ArrayData);
126
167
// Run the benchmark
127
168
BENCHMARK_MAIN ();
0 commit comments