Commit 2fef5f70 authored by Tom Jackson's avatar Tom Jackson Committed by Facebook Github Bot

Use "auto" with GENERATOR instead of std::function

Summary: Now that we're using C++14 more broadly, we should use it to improve generator performance. This speeds up a microbenchmark >5x by removing type erasure.

Reviewed By: philippv

Differential Revision: D6398730

fbshipit-source-id: 5809058a3b5ff0e66fd4b1e8954698944e1a7d09
parent 3e19d28a
...@@ -503,9 +503,8 @@ Yield generator(Source&& source) { ...@@ -503,9 +503,8 @@ Yield generator(Source&& source) {
* *
* auto gen = GENERATOR(int) { yield(1); yield(2); }; * auto gen = GENERATOR(int) { yield(1); yield(2); };
*/ */
#define GENERATOR(TYPE) \ #define GENERATOR(TYPE) \
::folly::gen::detail::GeneratorBuilder<TYPE>() + \ ::folly::gen::detail::GeneratorBuilder<TYPE>() + [=](auto&& yield)
[=](const std::function<void(TYPE)>& yield)
/* /*
* empty() - for producing empty sequences. * empty() - for producing empty sequences.
......
...@@ -140,11 +140,11 @@ BENCHMARK_DRAW_LINE() ...@@ -140,11 +140,11 @@ BENCHMARK_DRAW_LINE()
BENCHMARK(Fib_Sum_NoGen, iters) { BENCHMARK(Fib_Sum_NoGen, iters) {
int s = 0; int s = 0;
while (iters--) { while (iters--) {
auto fib = [](int limit) -> vector<int> { auto fib = [](size_t limit) -> vector<int> {
vector<int> ret; vector<int> ret;
int a = 0; int a = 0;
int b = 1; int b = 1;
for (int i = 0; i * 2 < limit; ++i) { for (size_t i = 0; i < limit; i += 2) {
ret.push_back(a += b); ret.push_back(a += b);
ret.push_back(b += a); ret.push_back(b += a);
} }
...@@ -168,11 +168,30 @@ BENCHMARK_RELATIVE(Fib_Sum_Gen, iters) { ...@@ -168,11 +168,30 @@ BENCHMARK_RELATIVE(Fib_Sum_Gen, iters) {
yield(b += a); yield(b += a);
} }
}; };
// Early stopping implemented with exceptions.
s += fib | take(testSize.load()) | sum; s += fib | take(testSize.load()) | sum;
} }
folly::doNotOptimizeAway(s); folly::doNotOptimizeAway(s);
} }
BENCHMARK_RELATIVE(Fib_Sum_Gen_Limit, iters) {
int s = 0;
while (iters--) {
size_t limit = testSize.load();
auto fib = GENERATOR(int) {
int a = 0;
int b = 1;
for (size_t i = 0; i < limit; i += 2) {
yield(a += b);
yield(b += a);
}
};
// No early stopping.
s += fib | sum;
}
folly::doNotOptimizeAway(s);
}
struct FibYielder { struct FibYielder {
template <class Yield> template <class Yield>
void operator()(Yield&& yield) const { void operator()(Yield&& yield) const {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment