Last active
April 26, 2022 22:33
-
-
Save Aposhian/7374d1af1f4cfdf99750410b14b4d0ac to your computer and use it in GitHub Desktop.
std::transform benchmarking
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <benchmark/benchmark.h> | |
#include <vector> | |
#include <algorithm> | |
#include <execution> | |
struct data { | |
int a; | |
int b; | |
int c; | |
}; | |
std::vector<int> resizer(std::vector<struct data> input) { | |
std::vector<int> output(input.size()); | |
std::transform( | |
input.begin(), | |
input.end(), | |
output.begin(), | |
[](const auto & data) { | |
return data.a + data.b + data.c; | |
} | |
); | |
return output; | |
} | |
std::vector<int> resizer_parallel(std::vector<struct data> input) { | |
std::vector<int> output(input.size()); | |
std::transform( | |
std::execution::par_unseq, | |
input.begin(), | |
input.end(), | |
output.begin(), | |
[](const auto & data) { | |
return data.a + data.b + data.c; | |
} | |
); | |
return output; | |
} | |
std::vector<int> reserver(std::vector<struct data> input) { | |
std::vector<int> output; | |
output.reserve(input.size()); | |
std::transform( | |
input.begin(), | |
input.end(), | |
std::back_inserter(output), | |
[](const auto & data) { | |
return data.a + data.b + data.c; | |
} | |
); | |
return output; | |
} | |
std::vector<int> for_loop(std::vector<struct data> input) { | |
std::vector<int> output; | |
for (const auto & data : input) { | |
output.push_back(data.a + data.b + data.c); | |
} | |
return output; | |
} | |
std::vector<int> reserve_for_loop(std::vector<struct data> input) { | |
std::vector<int> output; | |
output.reserve(input.size()); | |
for (const auto & data : input) { | |
output.push_back(data.a + data.b + data.c); | |
} | |
return output; | |
} | |
static constexpr size_t NUM_ELEMENTS = 1000000; | |
void generate_input(std::vector<struct data> & input) { | |
input.reserve(NUM_ELEMENTS); | |
for (int i = 0; i < NUM_ELEMENTS; ++i) { | |
input[i] = { | |
.a = rand(), | |
.b = rand(), | |
.c = rand() | |
}; | |
} | |
} | |
static void TestResizer(benchmark::State& state) { | |
std::vector<struct data> input; | |
generate_input(input); | |
// Code inside this loop is measured repeatedly | |
for (auto _ : state) { | |
benchmark::DoNotOptimize(input); | |
benchmark::DoNotOptimize(resizer(input)); | |
benchmark::ClobberMemory(); | |
} | |
} | |
// Register the function as a benchmark | |
BENCHMARK(TestResizer); | |
static void TestReserver(benchmark::State& state) { | |
// Code before the loop is not measured | |
std::vector<struct data> input; | |
generate_input(input); | |
for (auto _ : state) { | |
benchmark::DoNotOptimize(input); | |
benchmark::DoNotOptimize(reserver(input)); | |
benchmark::ClobberMemory(); | |
} | |
} | |
BENCHMARK(TestReserver); | |
static void TestResizerParallel(benchmark::State& state) { | |
// Code before the loop is not measured | |
std::vector<struct data> input; | |
generate_input(input); | |
for (auto _ : state) { | |
benchmark::DoNotOptimize(input); | |
benchmark::DoNotOptimize(resizer_parallel(input)); | |
benchmark::ClobberMemory(); | |
} | |
} | |
BENCHMARK(TestResizerParallel); | |
static void TestForLoop(benchmark::State& state) { | |
// Code before the loop is not measured | |
std::vector<struct data> input; | |
generate_input(input); | |
for (auto _ : state) { | |
benchmark::DoNotOptimize(input); | |
benchmark::DoNotOptimize(for_loop(input)); | |
benchmark::ClobberMemory(); | |
} | |
} | |
BENCHMARK(TestForLoop); | |
static void TestReserveForLoop(benchmark::State& state) { | |
// Code before the loop is not measured | |
std::vector<struct data> input; | |
generate_input(input); | |
for (auto _ : state) { | |
benchmark::DoNotOptimize(input); | |
auto output = reserve_for_loop(input); | |
benchmark::DoNotOptimize(output); | |
benchmark::ClobberMemory(); | |
} | |
} | |
BENCHMARK(TestReserveForLoop); | |
BENCHMARK_MAIN(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
test: | |
g++ -std=c++17 -O3 main.cpp -ltbb -lbenchmark -lpthread -o benchmark | |
./benchmark |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment