Skip to content

Instantly share code, notes, and snippets.

@ganler
Last active May 13, 2020 06:26
Show Gist options
  • Save ganler/7b77f8d722562b0059d1982bede733d4 to your computer and use it in GitHub Desktop.
Save ganler/7b77f8d722562b0059d1982bede733d4 to your computer and use it in GitHub Desktop.
/*
-------------------------------------------------------------------------------
Best matrial(I think) currently:
https://luncliff.github.io/coroutine/ppt/%5BEng%5DExploringTheCppCoroutine.pdf
= [Donald Knuth] Coroutines are functions that can suspend and resume their \
execution while keeping their state.
= The coroutine in C++ 20 standard are stackless.
-------------------------------------------------------------------------------
= Key concepts:
>>> [Routine]: An ordered group of instrutions. [instr0 -> instr1 -> ...]
>>> A @ [Invocation]: Start of a routine. (say, `call`)
>>> B @ [Activation]: Jump into some point of the routine. (say instr1)
>>> C @ [Suspension]: Jump to another routine's point without finalization.
>>> D @ [Finalization]: Finished the routine. (say, `return`)
>>> A routine has 4 operands:
Invoke/Finalize/Suspend/Resume
>>> [[Subroutine]]: A routine that supports Invoke/Finalize. (Suspend/Resume not supported)
>>> [Process]: A set of routines.
>>> [Thread]: The abstraction of a control flow in a process. (e.g. 1 CPU core)
>>> [[Coroutine]]: supports all 4 operands.
-------------------------------------------------------------------------------
*/
#include <experimental/coroutine>
#include <experimental/generator>
#include <experimental/resumable>
#include <utility>
#include <iostream>
#include <chrono>
#include <vector>
using namespace std;
using namespace std::experimental;
generator<size_t> co_fibonacci(size_t n) {
size_t a = 0, b = 1;
while (n-- > 0) {
co_yield a += b;
swap(a, b);
}
}
vector<size_t> normal_fibonacci(size_t n) {
vector<size_t> ret{};
ret.reserve(n);
size_t a = 0, b = 1;
while (n-- > 0) {
ret.push_back(a += b);
swap(a, b);
}
return ret;
}
template <typename I> generator<I> range(I r) { for (I i = 0; i < r; ++i) co_yield i; }
int main() {
using clk_t = chrono::high_resolution_clock;
constexpr size_t size = 300;
auto bench = [size](auto&& callback, string_view name) {
auto begin = clk_t::now();
for (auto v : callback(size)) cout << v << ' ';
cout << '\n' << chrono::duration<double, milli>(clk_t::now() - begin).count() << " ms for " << name << endl;
};
for (auto _ : range(10)) {
bench(normal_fibonacci, "normal");
bench(co_fibonacci, "coroutine");
}
cin.get();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment