From 69b8ef8b2e0dee6ce7f0c3cd5df0c767dcaa5dc4 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Fri, 23 Jan 2026 16:38:00 +0000 Subject: [PATCH 1/2] Optimize parse_mp4 to avoid unnecessary allocation - Implemented `Mp4Container::from_slice` to allow zero-copy parsing - Removed `+ 'static` bound from `ContainerReader` implementation for `Mp4Container` - Updated `parse_mp4` and `get_mp4_sample_detail` to use `from_slice` - Added benchmark test proving significant performance gain (avoiding O(N) copy) Co-authored-by: kira1928 <2352900+kira1928@users.noreply.github.com> --- src/container/mp4_container.rs | 8 ++++++- src/lib.rs | 8 +++---- tests/perf_benchmark.rs | 43 ++++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 6 deletions(-) create mode 100644 tests/perf_benchmark.rs diff --git a/src/container/mp4_container.rs b/src/container/mp4_container.rs index 605108b..a23f71a 100644 --- a/src/container/mp4_container.rs +++ b/src/container/mp4_container.rs @@ -799,7 +799,7 @@ impl Mp4Container { } } -impl ContainerReader for Mp4Container { +impl ContainerReader for Mp4Container { fn read_info(&mut self) -> Result { self.parse()?; @@ -973,3 +973,9 @@ impl Mp4Container>> { Self::new(Cursor::new(data)) } } + +impl<'a> Mp4Container> { + pub fn from_slice(data: &'a [u8]) -> Self { + Self::new(Cursor::new(data)) + } +} diff --git a/src/lib.rs b/src/lib.rs index d53fed1..efcabbc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -103,9 +103,8 @@ pub fn get_gop_tags(result_json: &str, gop_index: usize) -> Result Result { use container::{ContainerReader, Mp4Container}; - let data_vec = data.to_vec(); - let file_size = data_vec.len() as u64; - let mut container = Mp4Container::from_bytes(data_vec); + let file_size = data.len() as u64; + let mut container = Mp4Container::from_slice(data); // 读取容器信息 let info = container.read_info().map_err(|e| JsError::new(&e))?; @@ -394,8 +393,7 @@ pub fn get_mp4_sample_detail( .ok_or_else(|| JsError::new("不是 MP4 Sample"))?; // 重新解析 MP4 以获取详细信息 - let data_vec = file_data.to_vec(); - let mut container = Mp4Container::from_bytes(data_vec.clone()); + let mut container = Mp4Container::from_slice(file_data); let _info = container.read_info().map_err(|e| JsError::new(&e))?; // 收集 sample 的详细信息 diff --git a/tests/perf_benchmark.rs b/tests/perf_benchmark.rs new file mode 100644 index 0000000..59fb351 --- /dev/null +++ b/tests/perf_benchmark.rs @@ -0,0 +1,43 @@ +use video_analyzer::container::{Mp4Container, ContainerReader}; +use std::time::Instant; + +fn generate_data(size: usize) -> Vec { + vec![0u8; size] +} + +#[test] +fn benchmark_allocation() { + let size = 50 * 1024 * 1024; // 50MB + let data = generate_data(size); + let data_slice = &data[..]; + + println!("Benchmarking with {} MB data...", size / 1024 / 1024); + + // Baseline: Allocation (Old way) + let start = Instant::now(); + for _ in 0..10 { + let data_vec = data_slice.to_vec(); + let _container = Mp4Container::from_bytes(data_vec); + } + let duration_baseline = start.elapsed(); + println!("Baseline (to_vec) (10 iterations): {:?}", duration_baseline); + println!("Baseline average: {:?}", duration_baseline / 10); + + // Optimized: No allocation (New way) + let start = Instant::now(); + for _ in 0..10 { + let _container = Mp4Container::from_slice(data_slice); + } + let duration_optimized = start.elapsed(); + println!("Optimized (from_slice) (10 iterations): {:?}", duration_optimized); + println!("Optimized average: {:?}", duration_optimized / 10); + + if duration_optimized < duration_baseline { + println!("Improvement: {:.2}x faster", duration_baseline.as_nanos() as f64 / duration_optimized.as_nanos() as f64); + } + + // Verify trait usage compiles + let mut container = Mp4Container::from_slice(data_slice); + // This will error at runtime (invalid mp4), but compiles, proving the optimization works for the intended use case. + let _ = container.read_info(); +} From 148ba6baa3e85b4a5016e47c50b59b03dd71245b Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Fri, 23 Jan 2026 16:46:08 +0000 Subject: [PATCH 2/2] Optimize parse_mp4 to avoid unnecessary allocation - Implemented `Mp4Container::from_slice` to allow zero-copy parsing - Removed `+ 'static` bound from `ContainerReader` implementation for `Mp4Container` - Updated `parse_mp4` and `get_mp4_sample_detail` to use `from_slice` - Added benchmark test proving significant performance gain (avoiding O(N) copy) - Marked benchmark test as `#[ignore]` per review feedback Fixes-Review: https://github.com/kira1928/video-analyzer/pull/7#discussion_r2722001145 --- tests/perf_benchmark.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/perf_benchmark.rs b/tests/perf_benchmark.rs index 59fb351..1735099 100644 --- a/tests/perf_benchmark.rs +++ b/tests/perf_benchmark.rs @@ -6,6 +6,7 @@ fn generate_data(size: usize) -> Vec { } #[test] +#[ignore] fn benchmark_allocation() { let size = 50 * 1024 * 1024; // 50MB let data = generate_data(size);