15 #if defined(LIBCOPP_MACRO_ENABLE_STD_COROUTINE) && LIBCOPP_MACRO_ENABLE_STD_COROUTINE
17 # if defined(PROJECT_LIBCOPP_SAMPLE_HAS_CHRONO) && PROJECT_LIBCOPP_SAMPLE_HAS_CHRONO
19 # define CALC_CLOCK_T std::chrono::system_clock::time_point
20 # define CALC_CLOCK_NOW() std::chrono::system_clock::now()
21 # define CALC_MS_CLOCK(x) static_cast<int>(std::chrono::duration_cast<std::chrono::milliseconds>(x).count())
22 # define CALC_NS_AVG_CLOCK(x, y) \
23 static_cast<long long>(std::chrono::duration_cast<std::chrono::nanoseconds>(x).count() / (y ? y : 1))
25 # define CALC_CLOCK_T clock_t
26 # define CALC_CLOCK_NOW() clock()
27 # define CALC_MS_CLOCK(x) static_cast<int>((x) / (CLOCKS_PER_SEC / 1000))
28 # define CALC_NS_AVG_CLOCK(x, y) (1000000LL * static_cast<long long>((x) / (CLOCKS_PER_SEC / 1000)) / (y ? y : 1))
31 using benchmark_callable_future_type = copp::callable_future<int64_t>;
32 using benchmark_generator_future_type = copp::generator_future<int64_t>;
34 std::vector<std::unique_ptr<benchmark_callable_future_type>> g_benchmark_callable_list;
35 std::vector<benchmark_generator_future_type> g_benchmark_generator_list;
37 int recursive_count = 100;
38 int max_task_number = 100000;
40 benchmark_callable_future_type run_benchmark(
size_t idx,
int left_recursive_count,
41 benchmark_generator_future_type* first_hang) {
42 int64_t result = left_recursive_count;
43 if (
nullptr != first_hang) {
44 auto gen_res = co_await *first_hang;
50 if (left_recursive_count > 1) {
51 auto gen_res = co_await run_benchmark(idx, left_recursive_count - 1,
nullptr);
59 g_benchmark_callable_list.reserve(
static_cast<size_t>(max_task_number));
60 g_benchmark_generator_list.reserve(
static_cast<size_t>(max_task_number));
62 printf(
"### Round: %d ###\n", index);
65 for (
int i = 0; i < max_task_number; ++i) {
66 g_benchmark_generator_list.emplace_back(
67 benchmark_generator_future_type([](benchmark_generator_future_type::context_pointer_type) {}));
70 time_t begin_time = time(
nullptr);
74 while (g_benchmark_callable_list.size() <
static_cast<size_t>(max_task_number)) {
75 size_t idx = g_benchmark_callable_list.size();
76 g_benchmark_callable_list.push_back(std::unique_ptr<benchmark_callable_future_type>(
77 new benchmark_callable_future_type(run_benchmark(idx, recursive_count, &g_benchmark_generator_list[idx]))));
80 time_t end_time = time(
nullptr);
82 printf(
"create %d callable(s) and generator(s), cost time: %d s, clock time: %d ms, avg: %lld ns\n", max_task_number,
83 static_cast<int>(end_time - begin_time),
CALC_MS_CLOCK(end_clock - begin_clock),
86 begin_time = end_time;
87 begin_clock = end_clock;
90 long long real_switch_times =
static_cast<long long>(max_task_number) * recursive_count;
92 for (
int i = 0; i < max_task_number; ++i) {
93 g_benchmark_generator_list[i].get_context()->set_value(i);
96 end_time = time(
nullptr);
98 printf(
"resume %d callable(s) and generator(s) for %lld times, cost time: %d s, clock time: %d ms, avg: %lld ns\n",
99 max_task_number, real_switch_times,
static_cast<int>(end_time - begin_time),
102 begin_time = end_time;
103 begin_clock = end_clock;
105 g_benchmark_callable_list.clear();
107 end_time = time(
nullptr);
109 printf(
"remove %d callable(s), cost time: %d s, clock time: %d ms, avg: %lld ns\n", max_task_number,
110 static_cast<int>(end_time - begin_time),
CALC_MS_CLOCK(end_clock - begin_clock),
114 int main(
int argc,
char* argv[]) {
115 puts(
"###################### std callable - recursive ###################");
116 printf(
"########## Cmd:");
117 for (
int i = 0; i < argc; ++i) {
118 printf(
" %s", argv[i]);
123 max_task_number = atoi(argv[1]);
127 recursive_count = atoi(argv[2]);
130 for (
int i = 1; i <= 5; ++i) {
137 puts(
"std coroutine is not supported by current compiler.");
#define CALC_NS_AVG_CLOCK(x, y)
static void benchmark_round(int index)