-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Deploying to gh-pages from @ 0c426c6 🚀
- Loading branch information
Showing
7 changed files
with
855 additions
and
3 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
#include <benchmark/benchmark.h> | ||
|
||
#include <ranges> | ||
#include <vector> | ||
|
||
#include "any_view.hpp" | ||
|
||
static void BM_vector(benchmark::State& state) { | ||
std::vector v = | ||
std::views::iota(0, state.range(0)) | std::ranges::to<std::vector>(); | ||
for (auto _ : state) { | ||
for (auto i : v) { | ||
benchmark::DoNotOptimize(i); | ||
} | ||
} | ||
} | ||
// Register the function as a benchmark | ||
BENCHMARK(BM_vector)->RangeMultiplier(2)->Range(1 << 10, 1 << 18); | ||
|
||
// Define another benchmark | ||
static void BM_AnyView(benchmark::State& state) { | ||
std::vector v = | ||
std::views::iota(0, state.range(0)) | std::ranges::to<std::vector>(); | ||
std::ranges::any_view<int&> av(std::views::all(v)); | ||
for (auto _ : state) { | ||
for (auto i : av) { | ||
benchmark::DoNotOptimize(i); | ||
} | ||
} | ||
} | ||
BENCHMARK(BM_AnyView)->RangeMultiplier(2)->Range(1 << 10, 1 << 18); |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
#include <benchmark/benchmark.h> | ||
|
||
#include <random> | ||
#include <ranges> | ||
#include <vector> | ||
|
||
#include "any_view.hpp" | ||
#include "widget.hpp" | ||
|
||
namespace { | ||
|
||
constexpr auto MaxSize = 1 << 18; | ||
|
||
auto generate_random_widgets() { | ||
std::vector<lib::Widget> widgets; | ||
widgets.reserve(MaxSize); | ||
|
||
static const char alphanum[] = | ||
"0123456789" | ||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" | ||
"abcdefghijklmnopqrstuvwxyz"; | ||
std::random_device char_dev; | ||
std::mt19937 char_rng(char_dev()); | ||
std::uniform_int_distribution<std::mt19937::result_type> char_dist( | ||
0, sizeof(alphanum) - 1); | ||
|
||
std::random_device len_dev; | ||
std::mt19937 len_rng(len_dev()); | ||
std::uniform_int_distribution<std::mt19937::result_type> len_dist(1, 30); | ||
|
||
auto gen_next_str = [&]() { | ||
int len = len_dist(len_rng); | ||
std::string tmp_s; | ||
tmp_s.reserve(len); | ||
|
||
for (int i = 0; i < len; ++i) { | ||
tmp_s.push_back(alphanum[char_dist(char_rng)]); | ||
} | ||
|
||
return tmp_s; | ||
}; | ||
|
||
std::random_device w_dev; | ||
std::mt19937 w_rng(w_dev()); | ||
std::uniform_int_distribution<int> w_dist(0, 100); | ||
|
||
auto gen_size = [&] { return w_dist(w_rng); }; | ||
|
||
for (auto i = 0; i < MaxSize; ++i) { | ||
widgets.push_back(lib::Widget{gen_next_str(), gen_size()}); | ||
} | ||
return widgets; | ||
} | ||
|
||
const auto global_widgets = generate_random_widgets(); | ||
} // namespace | ||
|
||
using namespace lib; | ||
|
||
static void BM_AnyViewPipeline(benchmark::State& state) { | ||
lib::UI1 ui1{global_widgets | std::views::take(state.range(0)) | | ||
std::ranges::to<std::vector>()}; | ||
for (auto _ : state) { | ||
for (auto const& name : ui1.getWidgetNames()) { | ||
benchmark::DoNotOptimize(const_cast<std::string&>(name)); | ||
} | ||
} | ||
} | ||
BENCHMARK(BM_AnyViewPipeline)->RangeMultiplier(2)->Range(1 << 10, 1 << 18); | ||
|
||
static void BM_RawPipeline(benchmark::State& state) { | ||
lib::UI2 ui2{global_widgets | std::views::take(state.range(0)) | | ||
std::ranges::to<std::vector>()}; | ||
for (auto _ : state) { | ||
for (const auto& name : ui2.getWidgetNames()) { | ||
benchmark::DoNotOptimize(const_cast<std::string&>(name)); | ||
} | ||
} | ||
} | ||
// Register the function as a benchmark | ||
BENCHMARK(BM_RawPipeline)->RangeMultiplier(2)->Range(1 << 10, 1 << 18); | ||
|
||
static void BM_VectorCopy(benchmark::State& state) { | ||
lib::UI3 ui3{global_widgets | std::views::take(state.range(0)) | | ||
std::ranges::to<std::vector>()}; | ||
for (auto _ : state) { | ||
for (const auto& name : ui3.getWidgetNames()) { | ||
benchmark::DoNotOptimize(const_cast<std::string&>(name)); | ||
} | ||
} | ||
} | ||
// Register the function as a benchmark | ||
BENCHMARK(BM_VectorCopy)->RangeMultiplier(2)->Range(1 << 10, 1 << 18); | ||
|
||
static void BM_VectorRefWrapper(benchmark::State& state) { | ||
lib::UI4 ui4{global_widgets | std::views::take(state.range(0)) | | ||
std::ranges::to<std::vector>()}; | ||
for (auto _ : state) { | ||
for (const auto& nameRef : ui4.getWidgetNames()) { | ||
benchmark::DoNotOptimize(const_cast<std::string&>(nameRef.get())); | ||
} | ||
} | ||
} | ||
// Register the function as a benchmark | ||
BENCHMARK(BM_VectorRefWrapper)->RangeMultiplier(2)->Range(1 << 10, 1 << 18); |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
#include "widget.hpp" | ||
|
||
namespace lib { | ||
|
||
std::ranges::any_view<const std::string&> UI1::getWidgetNames() const { | ||
return widgets_ | std::views::filter([](const Widget& widget) { | ||
return widget.size > 10; | ||
}) | | ||
std::views::transform(&Widget::name); | ||
} | ||
|
||
bool UI2::FilterFn::operator()(const Widget& widget) const { | ||
return widget.size > 10; | ||
} | ||
|
||
const std::string& UI2::TransformFn::operator()(const Widget& widget) const { | ||
return widget.name; | ||
} | ||
|
||
std::ranges::transform_view< | ||
std::ranges::filter_view<std::ranges::ref_view<const std::vector<Widget>>, | ||
UI2::FilterFn>, | ||
UI2::TransformFn> | ||
UI2::getWidgetNames() const { | ||
return widgets_ | std::views::filter(UI2::FilterFn{}) | | ||
std::views::transform(UI2::TransformFn{}); | ||
} | ||
|
||
std::vector<std::string> UI3::getWidgetNames() const { | ||
return widgets_ | std::views::filter([](const Widget& widget) { | ||
return widget.size > 10; | ||
}) | | ||
std::views::transform(&Widget::name) | std::ranges::to<std::vector>(); | ||
} | ||
|
||
std::vector<std::reference_wrapper<const std::string>> UI4::getWidgetNames() | ||
const { | ||
return widgets_ | std::views::filter([](const Widget& widget) { | ||
return widget.size > 10; | ||
}) | | ||
std::views::transform( | ||
[](const Widget& widget) { return std::cref(widget.name); }) | | ||
std::ranges::to<std::vector>(); | ||
} | ||
|
||
} // namespace lib |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
#pragma once | ||
|
||
#include <ranges> | ||
#include <string> | ||
#include <vector> | ||
|
||
#include "any_view.hpp" | ||
|
||
namespace lib { | ||
|
||
struct Widget { | ||
std::string name; | ||
int size; | ||
}; | ||
|
||
struct UI1 { | ||
std::vector<Widget> widgets_; | ||
|
||
std::ranges::any_view<const std::string&> getWidgetNames() const; | ||
}; | ||
|
||
struct UI2 { | ||
std::vector<Widget> widgets_; | ||
// cannot use lambda because we need to spell the type of the view | ||
struct FilterFn { | ||
bool operator()(const Widget&) const; | ||
}; | ||
|
||
struct TransformFn { | ||
const std::string& operator()(const Widget&) const; | ||
}; | ||
std::ranges::transform_view< | ||
std::ranges::filter_view<std::ranges::ref_view<const std::vector<Widget>>, | ||
FilterFn>, | ||
TransformFn> | ||
getWidgetNames() const; | ||
}; | ||
|
||
struct UI3 { | ||
std::vector<Widget> widgets_; | ||
|
||
std::vector<std::string> getWidgetNames() const; | ||
}; | ||
|
||
struct UI4 { | ||
std::vector<Widget> widgets_; | ||
|
||
std::vector<std::reference_wrapper<const std::string>> getWidgetNames() const; | ||
}; | ||
|
||
|
||
|
||
} // namespace lib |