perf(pdu)!: avoid copying input events in FastPathInput - #1975
uchouT (uchouT) wants to merge 2 commits into
Conversation
`FastPathInput` now holds `Cow<'a, [FastPathInputEvent]>`. BREAKING CHANGE: `FastPathInput` now has a lifetime parameter. Signed-off-by: uchouT <i@uchout.moe>
There was a problem hiding this comment.
PR #1975 makes FastPathInput a borrowing PDU (Cow<'a, [FastPathInputEvent]> plus an OwnedFastPathInput alias) and drops the per-chunk to_vec() in ActiveStage::process_fastpath_input. Independently verified: wire format unchanged; the 1..=255 event-count invariant holds in new/single/Arbitrary and is preserved by into_owned; the free decode lifetime is sound because decoding always yields Cow::Owned; the borrowed chunk is encoded synchronously so no borrow escapes. The only broken consumer (tuple construction in workspace-excluded ironrdp-client-glutin) predates this PR under a FIXME exclusion; the breaking change is explicit (!). protocol and skeptical found no defects; the single valid code-compressor style finding is confirmed and accepted.
There was a problem hiding this comment.
Ownership refactor of FastPathInput from Vec to Cow<'a, [..]> with impl_pdu_borrowing!/IntoOwned, a free-lifetime Decode, and an Into<Cow>-based new(); ActiveStage now encodes the borrowed chunk without the prior to_vec() copy. Independently verified: the wire format, 1..=255 event-count invariant (new/single/into_owned/Arbitrary), 255-event chunking, and encode/decode symmetry are preserved; all in-workspace call sites (server, session, testsuite) use the new signatures correctly and the macro-generated DecodeOwned works with the free-lifetime Decode. No protocol or correctness defect found. Published one low-severity advisory (refined) on the semver-breaking public API change whose motivating perf win is small and unmeasured, corroborated by the tuple-construction call site in the workspace-excluded glutin client that no longer compiles.
- [skeptical] Breaking public API change whose motivating perf win is small and unmeasured — low 🟡 — crates/ironrdp-pdu/src/input/fast_path.rs
FastPathInput gains a lifetime parameter, a Cow<'a, [FastPathInputEvent]> field, an Into<Cow>-based new(), and an OwnedFastPathInput alias — a semver-breaking public API change (acknowledged by '!'). The benefit is removal of one to_vec() allocation per <=255-event chunk in ActiveStage::process_fastpath_input, while the client batcher typically produces 1-2 event batches and no benchmark accompanies the change. The break is concrete: the workspace-excluded glutin client constructs FastPathInput(fastpath_events) tuple-style with a Vec and no longer compiles, though no in-workspace consumer breaks. Counterweights: the design mirrors the established borrowing-PDU convention (impl_pdu_borrowing! + IntoOwned, as in FormatDataResponse), and correctness/invariant handling checks out. Low severity: advisory API-cost/benefit tradeoff, no correctness or protocol impact.
FastPathInputheldVec<FastPathInputEvent>, forcingActiveStage::process_fastpath_inputto copy each chunk before encoding (the// PERF: unnecessary copythere). It now holdsCow<'a, [FastPathInputEvent]>andnew()takesimpl Into<Cow<..>>, matchingFormatDataResponse::new_data.Found this PERF comment when I was looking through the relevant code and resolved it while I was at it. Haven't observed the exact benefit.