2个不稳定版本
0.2.0 | 2024年3月17日 |
---|---|
0.1.0 | 2023年11月8日 |
#950 in 异步
59 每月下载量
14KB
141 行
relaxed_channel
异步-channel包装器,在重管道上性能更优
问题
当读者(持有 Receiver
)比作者(持有 Sender
)快时,通道的长度将始终较低。通常,在读取一条消息后,一个读者任务会在尝试读取下一条消息时遇到空通道,并立即将自己设置为等待唤醒,以便在下一条消息发送时被唤醒。这意味着在发送下一条消息时,作者必须花费大量时间在tokio运行时标记接收任务唤醒。
(当管道变得重时,这个时间部分是显著的,大约每秒数百万条消息。)
随着读者数量的增加,这种影响也会增加(因为需要唤醒的读者更多),所以接收端的并行性要求越高,作者(或多个作者)的速度就越慢。
解决方案
在读取消息并遇到空通道时
- 通道为空 => 这意味着我们处理速度比作者生成数据的速度快。
- 不要浪费读者的时间,而是不是标记自己等待唤醒,而是睡眠,例如100ms。
- 100ms后,执行正常的
Receiver::recv()
检查消息,只有在这个时候才标记自己等待唤醒,如果仍然没有可用的消息。
这意味着每个读者最多每100ms被作者唤醒一次。
这个crate提供了 RelaxedReceiver
,它包装了常规的 async_channel::Receiver
以添加此行为。
请注意,这种设计使得所有读者可能同时睡眠100ms,因此为了不降低读者的速度,通道的容量必须足够大,可以容纳在那段时间内可能到达的更多消息。
依赖项
~3–4MB
~67K SLoC