Skip to content

Commit 8ae79e8

Browse files
committed
adding benchmark
1 parent bab9d66 commit 8ae79e8

File tree

2 files changed

+52
-12
lines changed

2 files changed

+52
-12
lines changed

README.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,44 @@ int main(int argc, char *argv[])
8989
}
9090
```
9191
92+
Benchmark
93+
-------
94+
We can observe speed ups for structure of arrays vs array of structs with the toy program benchmark.cc
95+
Here are the results using Visual Studio 2022 on Release mode on my laptop.
96+
97+
```
98+
benchmark results ==============
99+
soa sort time 0.126592
100+
vec sort time 0.312302
101+
soa timestamp avg time 0.0018725
102+
vec timestamp avg time 0.0052643
103+
```
104+
105+
The benchmark contains a small program concerning simulated sensor measurements. With a straightforward array of structs, we store metadata together with the actual sensor data together and then just push_back() these onto an std::vector.
106+
```c++
107+
struct SensorData {
108+
std::array<double, 18> xyz;
109+
110+
struct Measurement {
111+
Id sensor_id;
112+
Id object_id;
113+
double timestamp;
114+
SensorData data;
115+
};
116+
117+
...
118+
119+
std::vector<Measurement> measurements_vec;
120+
measurements_vec.push_back(m);
121+
```
122+
Alternatively, we could split the metadata and sensor data apart into a structure of arrays.
123+
```c++
124+
vapid::soa<Id, Id, double, SensorData> measurements_soa;
125+
soa.insert(m.sensor_id, m.object_id, m.timestamp, m.data);
126+
```
127+
128+
The benchmark times the cost of sorting by sensor_id, and then the cost of finding the average measurement timestamp using an std::vector vs a vapid::soa.
129+
92130
Manual Installation
93131
-----------
94132
Copy the vapid folder into your project and #include "vapid/soa.h"

benchmark.cc

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,9 @@ int main(int argc, char* argv[])
7171
{
7272
TicToc tictoc;
7373
double soa_sort_time = 0;
74-
double soa_sum_time = 0;
74+
double soa_ts_avg_time = 0;
7575
double vec_sort_time = 0;
76-
double vec_sum_time = 0;
76+
double vec_ts_avg_time = 0;
7777
TestCase t0 = TestCase::random();
7878
t0.measurements_soa.prepare_tmp();
7979

@@ -89,11 +89,12 @@ int main(int argc, char* argv[])
8989

9090
// soa sum
9191
tictoc.tic();
92-
double soa_sum = 0;
92+
double soa_ts_avg = 0;
9393
for (double d : t.measurements_soa.get_column<2>()) {
94-
soa_sum += d;
94+
soa_ts_avg += d;
9595
}
96-
soa_sum_time += tictoc.toc();
96+
soa_ts_avg /= t.measurements_soa.size();
97+
soa_ts_avg_time += tictoc.toc();
9798

9899
// vec sort
99100
tictoc.tic();
@@ -106,18 +107,19 @@ int main(int argc, char* argv[])
106107

107108
// vec sum
108109
tictoc.tic();
109-
double vec_sum = 0;
110+
double vec_ts_avg = 0;
110111
for (const auto& meas : t.measurements_vec) {
111-
vec_sum += meas.timestamp;
112+
vec_ts_avg += meas.timestamp;
112113
}
113-
vec_sum_time += tictoc.toc();
114+
vec_ts_avg /= t.measurements_vec.size();
115+
vec_ts_avg_time += tictoc.toc();
114116

115117
if (argc == 1234) {
116118
// prevent optimization
117119
std::cout << t.measurements_soa.get_column<0>()[0] << "\n";
118120
std::cout << t.measurements_vec[0].timestamp << "\n";
119-
std::cout << vec_sum << "\n";
120-
std::cout << soa_sum << "\n";
121+
std::cout << vec_ts_avg << "\n";
122+
std::cout << soa_ts_avg << "\n";
121123

122124
}
123125
}
@@ -126,8 +128,8 @@ int main(int argc, char* argv[])
126128
std::cout << "soa sort time " << soa_sort_time << std::endl;
127129
std::cout << "vec sort time " << vec_sort_time << std::endl;
128130

129-
std::cout << "soa sum time " << soa_sum_time << std::endl;
130-
std::cout << "vec sum time " << vec_sum_time << std::endl;
131+
std::cout << "soa timestamp avg time " << soa_ts_avg_time << std::endl;
132+
std::cout << "vec timestamp avg time " << vec_ts_avg_time << std::endl;
131133

132134
return 0;
133135
}

0 commit comments

Comments
 (0)