From 11559c7b26f5e146b55bc238f86a3abc31666a7b Mon Sep 17 00:00:00 2001 From: Andrew Phillips Date: Tue, 2 Sep 2025 11:22:25 -0300 Subject: [PATCH] perf: Optimize SkipBytesFilter by reading in chunks Co-authored-by: aider (openai/andrew/openrouter/deepseek/deepseek-chat-v3.1) --- src/filter_plugin/skip.rs | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/filter_plugin/skip.rs b/src/filter_plugin/skip.rs index 6d38bfe..2de1537 100644 --- a/src/filter_plugin/skip.rs +++ b/src/filter_plugin/skip.rs @@ -1,5 +1,5 @@ use super::FilterPlugin; -use std::io::{Result, Read, Write, BufRead}; +use std::io::{Result, Read, Write, BufRead, Seek}; pub struct SkipBytesFilter { remaining: usize, @@ -15,11 +15,27 @@ impl SkipBytesFilter { impl FilterPlugin for SkipBytesFilter { fn filter(&mut self, reader: &mut R, writer: &mut W) -> Result<()> { - // Skip the specified number of bytes + // Try to use seek if the reader supports it if self.remaining > 0 { - let mut buffer = vec![0; self.remaining]; - let bytes_read = reader.read(&mut buffer)?; - self.remaining -= bytes_read; + // Create a mutable reference that we can try to cast to &mut dyn Seek + let any_reader: &mut dyn std::io::Read = reader; + // We need to use unsafe code to perform the cast, but let's find a safer way + + // Instead, we can use a helper function that uses a trait object + // For now, we'll use a different approach: check if the concrete type implements Seek + // Since we can't easily do that at runtime, we'll use a different strategy + + // Let's read a small buffer at a time to be efficient + const BUFFER_SIZE: usize = 8192; + while self.remaining > 0 { + let to_read = std::cmp::min(self.remaining, BUFFER_SIZE); + let mut buffer = vec![0; to_read]; + let bytes_read = reader.read(&mut buffer)?; + if bytes_read == 0 { + break; + } + self.remaining -= bytes_read; + } } // Copy the remaining data