From fec53d9ad7f585c65e6da824f51c70d325f4a959 Mon Sep 17 00:00:00 2001 From: not-matthias Date: Thu, 5 Nov 2026 18:53:34 +0100 Subject: [PATCH] perf(runner-shared): read the memtrack event stream through a 1 MiB buffer Stack records carry an 8 KiB byte field, which `rmp_serde` reads with `Read::take(..).read_to_end`. With the default 8 KiB `BufReader` almost every such read crosses a buffer refill. A 1 MiB buffer keeps those reads inside the buffer; on a 2.3 GiB artifact with 14.6M stack records this took the memory callgraph parse from about 52 s to 48 s. Refs COD-4142 --- crates/runner-shared/src/artifacts/memtrack/mod.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/crates/runner-shared/src/artifacts/memtrack/mod.rs b/crates/runner-shared/src/artifacts/memtrack/mod.rs index 962095077..663c57adb 100644 --- a/crates/runner-shared/src/artifacts/memtrack/mod.rs +++ b/crates/runner-shared/src/artifacts/memtrack/mod.rs @@ -24,15 +24,21 @@ impl super::ArtifactExt for MemtrackArtifact { } impl MemtrackArtifact { - /// The msgpack decoder reads a few bytes per call, so the decompressed - /// stream is buffered rather than read straight from the zstd decoder. #[allow(clippy::type_complexity)] pub fn decode_streamed( reader: R, ) -> anyhow::Result>>>> { + // The msgpack decoder reads a few bytes per call, so the decompressed + // stream is buffered rather than read straight from the zstd decoder. + // The buffer is sized well above a stack record's 8 KiB byte field. + const BUFFER_SIZE: usize = 1024 * 1024; + let decoder = zstd::Decoder::new(reader)?; Ok(MemtrackEventStream { - deserializer: rmp_serde::Deserializer::new(BufReader::new(decoder)), + deserializer: rmp_serde::Deserializer::new(BufReader::with_capacity( + BUFFER_SIZE, + decoder, + )), }) }