Skip to content

Commit ab1861d

Browse files
committed
fix bad behavior when storing large moveable objects
1 parent 7760d45 commit ab1861d

File tree

2 files changed

+71
-30
lines changed

2 files changed

+71
-30
lines changed

benchmarks.cc

Lines changed: 70 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,41 @@ std::default_random_engine gen;
1010
std::uniform_int_distribution<Id> sensor_id_gen(0, 100);
1111
std::uniform_int_distribution<Id> object_id_gen(0, 10);
1212
std::uniform_real_distribution<double> real_gen(-10.0, 10.0);
13+
std::uniform_int_distribution<int> char_gen('a', 'z');
1314

14-
struct SensorData {
15+
16+
struct ArraySensorData {
1517
std::array<double, 18> xyz;
1618

17-
static SensorData random() {
18-
SensorData s;
19+
static ArraySensorData random() {
20+
ArraySensorData s;
1921
for (size_t i = 0; i < s.xyz.size(); ++i) {
2022
s.xyz[i] = real_gen(gen);
2123
}
2224
return s;
2325
};
2426
};
2527

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+
};
3146

47+
template <typename SensorData>
3248
struct Measurement {
3349
Id sensor_id;
3450
Id object_id;
@@ -45,20 +61,15 @@ struct Measurement {
4561
}
4662
};
4763

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>
5465
struct TestCase {
5566
vapid::soa<Id, Id, double, SensorData> measurements_soa;
56-
std::vector<Measurement> measurements_vec;
67+
std::vector<Measurement<SensorData>> measurements_vec;
5768

5869
static TestCase random() {
5970
TestCase t;
6071
for (int i = 0; i < 100000; ++i) {
61-
Measurement m = Measurement::random();
72+
Measurement<SensorData> m = Measurement<SensorData>::random();
6273
t.measurements_vec.push_back(m);
6374
t.measurements_soa.insert(m.sensor_id, m.object_id, m.timestamp, m.data);
6475
}
@@ -67,23 +78,35 @@ struct TestCase {
6778
}
6879
};
6980

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+
}
7194

72-
static void BM_SoaSortBySensorId(benchmark::State& state) {
95+
static void BM_SoaSortBySensorId_StringData(benchmark::State& state) {
7396
for (auto _ : state) {
7497
state.PauseTiming();
75-
auto soa = random_data.measurements_soa;
98+
auto soa = random_string_data.measurements_soa;
7699
state.ResumeTiming();
77100

78101
soa.sort_by_field<0>();
79102
benchmark::DoNotOptimize(soa.get_column<0>()[0]);
80103
}
81104
}
82105

83-
static void BM_VecSortBySensorId(benchmark::State& state) {
106+
static void BM_VecSortBySensorId_ArrayData(benchmark::State& state) {
84107
for (auto _ : state) {
85108
state.PauseTiming();
86-
auto vec = random_data.measurements_vec;
109+
auto vec = random_array_data.measurements_vec;
87110
state.ResumeTiming();
88111

89112
std::stable_sort(vec.begin(),
@@ -95,8 +118,23 @@ static void BM_VecSortBySensorId(benchmark::State& state) {
95118
}
96119
}
97120

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;
100138
for (auto _ : state) {
101139
double sum = 0;
102140
for (double d : soa.get_column<2>()) {
@@ -106,8 +144,8 @@ static void BM_SoaSumTimestamps(benchmark::State& state) {
106144
}
107145
}
108146

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;
111149
for (auto _ : state) {
112150
double sum = 0;
113151
for (const auto& meas : vec) {
@@ -119,9 +157,12 @@ static void BM_VecSumTimestamps(benchmark::State& state) {
119157

120158

121159
// 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);
126167
// Run the benchmark
127168
BENCHMARK_MAIN();

vapid/soa.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ namespace vapid {
202202
auto& dst = std::get<col_idx>(data_tmp_);
203203
dst.resize(src.size());
204204
for (size_t idx = 0; idx < src.size(); ++idx) {
205-
dst[idx] = src[sort_order_reference_[idx]];
205+
dst[idx] = std::move(src[sort_order_reference_[idx]]);
206206
}
207207
std::swap(src, dst);
208208
}

0 commit comments

Comments
 (0)