summaryrefslogtreecommitdiffstats
path: root/vespalib
diff options
context:
space:
mode:
authorHåvard Pettersen <havardpe@yahooinc.com>2022-11-15 14:40:38 +0000
committerHåvard Pettersen <havardpe@yahooinc.com>2022-11-15 14:40:38 +0000
commit9af0e6c6536d26049354c877f144dc1a93cf148b (patch)
tree2b98354a29d235f5a8e375d5c86833e05439218b /vespalib
parentf5cb948a5564d586ea3b166e96e9fd6d44086397 (diff)
adjust generator bench
also benchmark Sequence alternative
Diffstat (limited to 'vespalib')
-rw-r--r--vespalib/src/tests/coro/generator/generator_bench.cpp99
1 files changed, 70 insertions, 29 deletions
diff --git a/vespalib/src/tests/coro/generator/generator_bench.cpp b/vespalib/src/tests/coro/generator/generator_bench.cpp
index 664132b7ba4..7671a48b2e6 100644
--- a/vespalib/src/tests/coro/generator/generator_bench.cpp
+++ b/vespalib/src/tests/coro/generator/generator_bench.cpp
@@ -2,21 +2,14 @@
#include <vespa/vespalib/coro/generator.h>
#include <vespa/vespalib/util/benchmark_timer.h>
+#include <vespa/vespalib/util/sequence.h>
#include <vespa/vespalib/gtest/gtest.h>
#include <ranges>
#include <vector>
using vespalib::coro::Generator;
using vespalib::BenchmarkTimer;
-
-std::vector<size_t> make_data() __attribute__((noinline));
-std::vector<size_t> make_data(size_t size) {
- std::vector<size_t> data;
- for (size_t i = 0; i < size; ++i) {
- data.push_back(i);
- }
- return data;
-}
+using vespalib::Sequence;
template <std::ranges::input_range T>
size_t calc_sum(T&& values) {
@@ -27,32 +20,80 @@ size_t calc_sum(T&& values) {
return sum;
}
-size_t calc_sum_direct(const std::vector<size_t> &values) {
- return calc_sum(values);
+size_t calc_sum(Sequence<size_t> &seq) {
+ size_t sum = 0;
+ for (; seq.valid(); seq.next()) {
+ sum += seq.get();
+ }
+ return sum;
}
-size_t calc_sum_wrapped(const std::vector<size_t> &values) {
- return calc_sum([](const std::vector<size_t> &inner_values)->Generator<size_t>
- {
- for (auto&& value: inner_values) {
- co_yield value;
- }
- }(values));
+struct ValueRange {
+ using iterator_concept = std::input_iterator_tag;
+ using difference_type = std::ptrdiff_t;
+ using value_type = size_t;
+ size_t first;
+ size_t last;
+ ValueRange() noexcept : first(0), last(0) {}
+ ValueRange(size_t first_in, size_t last_in) noexcept
+ : first(first_in), last(last_in) {}
+ auto begin() noexcept { return ValueRange(first, last); }
+ auto end() const noexcept { return std::default_sentinel_t(); }
+ bool operator==(std::default_sentinel_t) const noexcept { return (first == last); }
+ ValueRange &operator++() noexcept { ++first; return *this; }
+ void operator++(int) noexcept { operator++(); }
+ size_t operator*() const noexcept { return first; }
+};
+
+size_t calc_sum_direct(size_t first, size_t last) {
+ return calc_sum(ValueRange(first, last));
+}
+
+Generator<size_t> gen_values(size_t first, size_t last) {
+ for (size_t i = first; i < last; ++i) {
+ co_yield i;
+ }
+}
+
+size_t calc_sum_generator(size_t first, size_t last) {
+ return calc_sum(gen_values(first, last));
+}
+
+struct MySeq : Sequence<size_t> {
+ size_t first;
+ size_t last;
+ MySeq(size_t first_in, size_t last_in)
+ : first(first_in), last(last_in) {}
+ bool valid() const override { return (first < last); }
+ size_t get() const override { return first; }
+ void next() override { ++first; }
+};
+
+size_t calc_sum_sequence(size_t first, size_t last) {
+ MySeq seq(first, last);
+ return calc_sum(seq);
}
-TEST(GeneratorBench, direct_vs_wrapped_vector_for_loop) {
- std::vector<size_t> data = make_data(100000);
- double direct_ms = BenchmarkTimer::benchmark([&data](){
- size_t sink = calc_sum_direct(data);
- (void) sink;
+TEST(GeneratorBench, direct_vs_generated_for_loop) {
+ size_t first = 0;
+ size_t last = 100000;
+ size_t res_direct = 0;
+ size_t res_generator = 1;
+ size_t res_sequence = 2;
+ double direct_ms = BenchmarkTimer::benchmark([first,last,&res_direct](){
+ res_direct = calc_sum_direct(first, last);
}, 5.0) * 1000.0;
fprintf(stderr, "direct: %g ms\n", direct_ms);
- double wrapped_ms = BenchmarkTimer::benchmark([&data](){
- size_t sink = calc_sum_wrapped(data);
- (void) sink;
- }, 5.0) * 1000.0;
- fprintf(stderr, "wrapped: %g ms\n", wrapped_ms);
- fprintf(stderr, "ratio: %g\n", (wrapped_ms/direct_ms));
+ double generator_ms = BenchmarkTimer::benchmark([first,last,&res_generator](){
+ res_generator = calc_sum_generator(first, last);
+ }, 5.0) * 1000.0;
+ fprintf(stderr, "generator: %g ms\n", generator_ms);
+ double sequence_ms = BenchmarkTimer::benchmark([first,last,&res_sequence](){
+ res_sequence = calc_sum_sequence(first, last);
+ }, 5.0) * 1000.0;
+ fprintf(stderr, "sequence: %g ms\n", sequence_ms);
+ fprintf(stderr, "ratio (generator/direct): %g\n", (generator_ms/direct_ms));
+ fprintf(stderr, "ratio (generator/sequence): %g\n", (generator_ms/sequence_ms));
}
GTEST_MAIN_RUN_ALL_TESTS()