make tokio dependency optional#160
Conversation
|
Thanks for sending us the PR! Does the channel you suggested actually "weigh" less? Currently, h3 only depends on the |
Depends by what metric. In terms of code being downloaded from crate.io it's roughly 50 times lighter. In terms of performance, and compiled size I have no idea (but I can check...). A motivation was to make it obvious that the crate is runtime independent and doesn't spawn tasks. With tokio as a dependency that is tricky to tell for most people, since some things in tokio require running inside a tokio runtime, while others don't. It's not the case here, but I almost decided not to use h3 because I didn't look close enough at first.
Same with Maybe I should have used |
|
I did a quick benchmark that seemed reasonable for this case and I would propose to change the PR and get rid of both use futures_util::StreamExt;
fn main() {
let w = noop_waker::noop_waker();
let mut cx = std::task::Context::from_waker(&w);
let cx = &mut cx;
#[cfg(feature = "async-channel")]
let (s, mut r) = async_channel::unbounded();
#[cfg(feature = "tokio")]
let (s, mut r) = tokio::sync::mpsc::unbounded_channel();
#[cfg(feature = "futures-channel")]
let (s, mut r) = futures_channel::mpsc::unbounded();
for i in 0..10_000_000u64 {
#[cfg(feature = "async-channel")]
let x = {
let _ = r.poll_next_unpin(cx);
s.try_send(i).unwrap();
r.poll_next_unpin(cx)
};
#[cfg(feature = "tokio")]
let x = {
let _ = r.poll_recv(cx);
s.send(i).unwrap();
r.poll_recv(cx)
};
#[cfg(feature = "futures-channel")]
let x = {
let _ = r.poll_next_unpin(cx);
s.unbounded_send(i).unwrap();
r.poll_next_unpin(cx)
};
std::hint::black_box(x);
}
} |
|
Performance characteristics for channels really depends on usage. They all chose different pros and cons, such as using a linked list versus arrays and blocks, instrusive collections, locks vs spinning, preferring allocating in For that reason, I tend to find Tokio's channel preferable because it sees more usage, and there are several active maintainers available to fix any bugs that are reported. |
Independent of the channel, I think it is a good idea to address in the readme that h3 is runtime independent. I will submit a PR for this. |
Thx, that helps.
That's why the benchmark looks the way it does. I suspect the channel signalling request ends will pretty much always be empty and at least half off the polls result in
I would have assumed that anything in To be clear, I only sent this PR because of the size and the "looks like depends on tokio runtime" concern, not performance. I just wanted to alleviate potential performance concerns with the benchmark. I personally would still prefer the smaller dependency, but it is pretty subjective, so feel free to close. I'm happy to send a PR for any variant mentioned in the thread otherwise. |
1464442 to
1f10a0b
Compare
The h3 crate depends on
tokio, but only uses it for the unbounded channel, which signals request completion. I would like to replace the use oftokio::sync::mpscwith a lighter alternative, or at least make it optional.This PR adds an optional dependency on
async-channeland makestokiooptional. Alternatively any other mpsc implementation or even aArc<Mutex<(VecDeque, Waker)>>should be sufficient.