2
0
mirror of https://github.com/boostorg/cobalt.git synced 2026-01-19 04:02:16 +00:00
Files
cobalt/doc/benchmarks.adoc
Klemens Morgenstern 45901641ac renamed to cobalt.
2023-10-16 21:42:07 +08:00

134 lines
2.9 KiB
Plaintext

= Benchmarks
__Run on 11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz__
== Posting to an executor
The benchmark is running the following code, with cobalt's task, `asio::awaitable` and `asio`'s
stackful coroutine (boost.context) based.
[source,cpp]
----
cobalt::task<void> atest()
{
for (std::size_t i = 0u; i < n; i++)
co_await asio::post(cobalt::use_op);
}
----
.results for 50M times in ms
[cols="1,1,1"]
|===
| |gcc 12 |clang 16
|cobalt | 2472 | 2098
|awaitable | 2432 | 2253
|stackful | 3655 | 3725
|===
== Running noop coroutine in parallel
This benchmark uses an `asio::experimental::channel` that has a size of zero,
to read & write in parallel to it. It uses <<gather, gather>> with cobalt
and an `awaitable_operator` in the `asio::awaitable`.
[source,cpp]
----
cobalt::task<void> atest()
{
asio::experimental::channel<void(system::error_code)> chan{co_await cobalt::this_coro::executor, 0u};
for (std::size_t i = 0u; i < n; i++)
co_await cobalt::gather(
chan.async_send(system::error_code{}, cobalt::use_task),
chan.async_receive(cobalt::use_task));
}
asio::awaitable<void> awtest()
{
asio::experimental::channel<void(system::error_code)> chan{co_await cobalt::this_coro::executor, 0u};
using boost::asio::experimental::awaitable_operators::operator&&;
for (std::size_t i = 0u; i < n; i++)
co_await (
chan.async_send(system::error_code{}, asio::use_awaitable)
&&
chan.async_receive(asio::use_awaitable));
}
----
.results for 3M times in ms
[cols="1,1,1"]
|===
| |gcc 12 |clang 16
|cobalt | 1563 | 1468
|awaitable | 2800 | 2805
|===
== Immediate
This benchmark utilizes the immediate completion, by using a channel
with a size of 1, so that every operation is immediate.
[source,cpp]
----
cobalt::task<void> atest()
{
asio::experimental::channel<void(system::error_code)> chan{co_await cobalt::this_coro::executor, 1u};
for (std::size_t i = 0u; i < n; i++)
{
co_await chan.async_send(system::error_code{}, cobalt::use_op);
co_await chan.async_receive(cobalt::use_op);
}
}
----
.result for 10M times in ms
[cols="1,1,1"]
|===
| |gcc 12 |clang 16
|cobalt | 1810 | 1864
|awaitable | 3109 | 4110
|stackful | 3922 | 4705
|===
== Channels
In this benchmark asio::experimental::channel and cobalt::channel get compared.
This is similar to the parallel test, but uses the `cobalt::channel` instead.
.result of running the test 3M times in ms
[cols="1,1,1"]
|===
| |gcc |clang
|cobalt | 500 | 350
|awaitable | 790 | 770
|stackful | 867 | 907
|===
== Operation Allocations
This benchmark compares the different possible solutions for the associated allocator of asynchronous operations
.result of running the test 2M times in ms
[cols="1,1,1"]
|===
| |gcc |clang
|std::allocator | 1136 | 1139
|cobalt::monotonic | 1149 | 1270
|pmr::monotonic | 1164 | 1173
|cobalt::sbo | 1021 | 1060
The latter method is used internally by cobalt.
|===