Skip to content
This repository has been archived by the owner on Sep 13, 2018. It is now read-only.

Commit

Permalink
Avoid quadratic complexity in poll()
Browse files Browse the repository at this point in the history
streaming::pipeline::server::Dispatch::poll() called poll on every
single entry of self.in_flight, and then removed at most one
element from that structure (via pop_front()).

So, the complexity is O(n^2) in the size of self.in_flight.

Calling poll() on the first entry of self.in_flight should be
sufficient, the other entries can be handled later. This reduces the
complexity to O(n).

This behavior can be significant if self.in_flight gets large, which can
happen if input is read very quickly. I triggered it with a simple
echo server fed from a unix domain socket:

$ time yes | head -n 1000 |  nc -U -N /tmp/sock >/dev/null
real	0m0.051s

$ time yes | head -n 10000 |  nc -U -N /tmp/sock >/dev/null
real	0m3.534s

$ time yes | head -n 20000 |  nc -U -N /tmp/sock >/dev/null
real	0m13.883s

With this patch, the runtime becomes linear and much faster:

$ time yes | head -n 1000 |  nc -U -N /tmp/sock >/dev/null
real	0m0.010s

$ time yes | head -n 10000 |  nc -U -N /tmp/sock >/dev/null
real	0m0.049s

$ time yes | head -n 20000 |  nc -U -N /tmp/sock >/dev/null
real	0m0.084s

$ time yes | head -n 100000 |  nc -U -N /tmp/sock >/dev/null
real	0m0.405s

$ time yes | head -n 1000000 |  nc -U -N /tmp/sock >/dev/null
real	0m3.738s
  • Loading branch information
jannic committed Mar 20, 2017
1 parent 6dacc75 commit 4e15957
Showing 1 changed file with 3 additions and 2 deletions.
5 changes: 3 additions & 2 deletions src/streaming/pipeline/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,9 @@ impl<P, T, B, S> super::advanced::Dispatch for Dispatch<S, T, P> where
}

fn poll(&mut self) -> Poll<Option<PipelineMessage<Self::In, Self::Stream, Self::Error>>, io::Error> {
for slot in self.in_flight.iter_mut() {
slot.poll();
match self.in_flight.front_mut() {
Some(slot) => slot.poll(),
_ => return Ok(Async::NotReady)
}

match self.in_flight.front() {
Expand Down

0 comments on commit 4e15957

Please sign in to comment.