From ce66efc045905751fc6d084a3d164b87f95d0810 Mon Sep 17 00:00:00 2001 From: Matthias Einwag Date: Sat, 8 May 2021 10:10:02 -0700 Subject: [PATCH] Use an `ArrayRangeSet` to store new ACKs This seems slightly more efficient than extending a `Vec`. Would probably be even more efficient if there would be an intersection method on `SentMap` insert of returning packet numbers one by one. Peak perf before: ``` Sent 1073741824 bytes on 1 streams in 1.77s (577.02 MiB/s) ``` After: ``` Sent 1073741824 bytes on 1 streams in 1.75s (584.25 MiB/s) ``` --- quinn-proto/src/connection/mod.rs | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/quinn-proto/src/connection/mod.rs b/quinn-proto/src/connection/mod.rs index da9001b97..073cda4ee 100644 --- a/quinn-proto/src/connection/mod.rs +++ b/quinn-proto/src/connection/mod.rs @@ -1066,21 +1066,19 @@ where }; // Avoid DoS from unreasonably huge ack ranges by filtering out just the new acks. - let newly_acked = ack - .iter() - .flat_map(|range| { - self.spaces[space] - .sent_packets - .range(range) - .map(|(&n, _)| n) - }) - .collect::>(); + let mut newly_acked = ArrayRangeSet::new(); + for range in ack.iter() { + for (&pn, _) in self.spaces[space].sent_packets.range(range) { + newly_acked.insert_one(pn); + } + } + if newly_acked.is_empty() { return Ok(()); } let mut ack_eliciting_acked = false; - for &packet in &newly_acked { + for packet in newly_acked.elts() { if let Some(info) = self.spaces[space].sent_packets.remove(&packet) { self.spaces[space].pending_acks.subtract(&info.acks); ack_eliciting_acked |= info.ack_eliciting;