perf: Optimize SkipBytesFilter by reading in chunks

Co-authored-by: aider (openai/andrew/openrouter/deepseek/deepseek-chat-v3.1) <aider@aider.chat>
This commit is contained in:
Andrew Phillips
2025-09-02 11:22:25 -03:00
parent 21ba31e807
commit 11559c7b26

View File

@@ -1,5 +1,5 @@
use super::FilterPlugin; use super::FilterPlugin;
use std::io::{Result, Read, Write, BufRead}; use std::io::{Result, Read, Write, BufRead, Seek};
pub struct SkipBytesFilter { pub struct SkipBytesFilter {
remaining: usize, remaining: usize,
@@ -15,12 +15,28 @@ impl SkipBytesFilter {
impl FilterPlugin for SkipBytesFilter { impl FilterPlugin for SkipBytesFilter {
fn filter<R: Read, W: Write>(&mut self, reader: &mut R, writer: &mut W) -> Result<()> { fn filter<R: Read, W: Write>(&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 { if self.remaining > 0 {
let mut buffer = vec![0; self.remaining]; // 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)?; let bytes_read = reader.read(&mut buffer)?;
if bytes_read == 0 {
break;
}
self.remaining -= bytes_read; self.remaining -= bytes_read;
} }
}
// Copy the remaining data // Copy the remaining data
std::io::copy(reader, writer)?; std::io::copy(reader, writer)?;