7 releases (breaking)
0.7.0 | Jan 18, 2023 |
---|---|
0.6.0 | Jan 9, 2023 |
0.5.0 | Jan 8, 2023 |
0.4.0 | Jan 6, 2023 |
0.1.0 | Jan 3, 2023 |
#895 in Concurrency
33 downloads per month
72KB
1K
SLoC
Gemino
A MPMC channel
What is Gemino
Gemino is an implementation of a multi producer multi consumer (MPMC) broadcasting channel where all receivers have the opportunity to receive all messages sent by all producers. The library has been designed with speed and ease of use in mind and offers both a blocking and asynchronous API which can be used at the same time.
If the data being sent through the channel implements Copy there are some nice optimisations that are (automatically) made which make the channel significantly faster. When using Copy, no locks are required for reads or writes. It is possible to detect a corrupt read after it's taken place eliminating the need for locks. This isn't the case with clone where arbitrary code needs to be run that depends on the memory inside the channel. For this reason locks must be used to ensure that writers do not overwrite a value that is being cloned. The overhead is high although the overall speed of the channel is still very fast and with my very rudimentary benchmarks still considerably faster than other broadcasting channel implementations.
Gemino was developed as a personal learning exercise, but I believe it is good enough to share and use.
Gemino is still in very early development, is lacking rigorous testing and makes use of unsafe as well as unstable features. Use at your own risk!
Unstable Features
Gemino makes use of the
unstable min_specialization
feature. This is the sound subset of the larger and
currently specialization
feature.
min_specialization
is stable enough that it is in use within the standard library. That being said it's still an
unstable feature,
requires nightly.
Why use Gemino?
- You need both async and blocking access to the same channel.
- You need multiple receivers and senders but are not concerned with data loss if a receiver falls behind.
- You need to be able to close the channel and have all parties be notified.
Why not use Gemino?
- Unstable nightly only features are something you want to avoid.
- Gemino uses unsafe and may exhibit undefined behaviour that we haven't seen or found yet.
- If you need to absolutely guarantee that all receivers get all the messages without fail Gemino is not for you.
Benchmarks
So far I've only written a couple of super basic benchmarks and I definitely need to do some more work to stress everything more thoroughly/correctly.
Currently, I'm only comparing against tokio::sync::broadcast and multiqueue.
Gemino is faster than Tokio implementation and slightly faster than multiqueue while being considerably more consistent than both. Being more consistent means that geminos latency should be more predictable than the other two.
Single threaded | ns/iter | +- | |
---|---|---|---|
gemino copy | 10211 | 283 | |
multiq copy | 10496 | 770 | |
gemino clone | 79118 | 1671 | |
multiq clone | 85375 | 2114 | |
4 readers 4 writers | |||
gemino copy | 368411 | 20533 | |
multiq copy | 1331904 | 277678 | |
gemino clone | 1028063 | 75103 | |
multiq clone | 1137864 | 298458 | |
4 readers 4 writers async | |||
+ | - | ||
gemino copy | 4164023 | 1413060 | 780273 |
tokio copy | 7347818 | 1639432 | 1613110 |
gemino clone | 7459048 | 3486077 | 326673 |
tokio clone | 8323468 | 7026741 | 80843 |
Single thread sequential
Four write threads + four read threads
Four write threads + four read threads + async
Dependencies
~0.7–6MB
~30K SLoC