Last active
December 5, 2022 13:18
-
-
Save nthery/5876bc9d1559775c4b2df834a78f65b9 to your computer and use it in GitHub Desktop.
Benchmark map-filter implemented with STL and ranges
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 <vector> | |
#include <functional> | |
#include <range/v3/all.hpp> | |
namespace rv= ranges::view; | |
inline bool is_odd(int n) { | |
return n & 1; | |
} | |
std::vector<int> map_filter_stl(const std::vector<int>& in) { | |
std::vector<int> out; | |
std::transform(in.begin(), in.end(), | |
std::back_inserter(out), | |
[](int n) { return n * 3; }); | |
out.erase(std::remove_if(out.begin(), out.end(), | |
std::not_fn(is_odd)), | |
out.end()); | |
return out; | |
} | |
std::vector<int> map_filter_range(const std::vector<int>& in) { | |
const auto map_filter = | |
rv::transform([](int n) { | |
return n * 3; | |
}) | | |
// Not supported by quick-bench version :-( rv::cache1 | | |
rv::filter([](int n) { | |
return is_odd(n); | |
}); | |
std::vector<int> out; | |
ranges::copy(in | map_filter, ranges::back_inserter(out)); | |
return out; | |
} | |
std::vector<int> range_copy_if(const std::vector<int>& in) { | |
std::vector<int> out; | |
const auto map = rv::transform([](int n) { | |
return n * 3; | |
}); | |
ranges::copy_if(in | map, ranges::back_inserter(out), is_odd); | |
return out; | |
} | |
std::vector<int> map_filter_hand_coded(const std::vector<int>& in) { | |
std::vector<int> out; | |
for (int n: in) { | |
const int x = n * 3; | |
if (is_odd(x)) { | |
out.push_back(x); | |
} | |
} | |
return out; | |
} | |
std::vector<int> make_vector() { | |
std::vector<int> v; | |
ranges::copy(rv::iota(0, 10000), ranges::back_inserter(v)); | |
return v; | |
} | |
static void STL(benchmark::State& state) { | |
const auto v = make_vector(); | |
for (auto _ : state) { | |
const auto out = map_filter_stl(v); | |
benchmark::DoNotOptimize(out); | |
} | |
} | |
BENCHMARK(STL); | |
static void RangesMapFilter(benchmark::State& state) { | |
const auto v = make_vector(); | |
for (auto _ : state) { | |
const auto out = map_filter_range(v); | |
benchmark::DoNotOptimize(out); | |
} | |
} | |
BENCHMARK(RangesMapFilter); | |
static void RangesCopyIf(benchmark::State& state) { | |
const auto v = make_vector(); | |
for (auto _ : state) { | |
const auto out = range_copy_if(v); | |
benchmark::DoNotOptimize(out); | |
} | |
} | |
BENCHMARK(RangesCopyIf); | |
static void HandCoded(benchmark::State& state) { | |
const auto v = make_vector(); | |
for (auto _ : state) { | |
const auto out = map_filter_hand_coded(v); | |
benchmark::DoNotOptimize(out); | |
} | |
} | |
BENCHMARK(HandCoded); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment