diff --git a/Cargo.toml b/Cargo.toml index 8a079446..4870c382 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,3 +42,7 @@ default = ["aes-crypto", "bzip2", "deflate", "time", "zstd"] [[bench]] name = "read_entry" harness = false + +[[bench]] +name = "read_metadata" +harness = false diff --git a/benches/read_metadata.rs b/benches/read_metadata.rs new file mode 100644 index 00000000..51f1f69e --- /dev/null +++ b/benches/read_metadata.rs @@ -0,0 +1,41 @@ +use bencher::{benchmark_group, benchmark_main}; + +use std::io::{Cursor, Write}; + +use bencher::Bencher; +use zip::{ZipArchive, ZipWriter}; + +const FILE_COUNT: usize = 15_000; +const FILE_SIZE: usize = 1024; + +fn generate_random_archive(count_files: usize, file_size: usize) -> Vec { + let data = Vec::new(); + let mut writer = ZipWriter::new(Cursor::new(data)); + let options = + zip::write::FileOptions::default().compression_method(zip::CompressionMethod::Stored); + + let bytes = vec![0u8; file_size]; + + for i in 0..count_files { + let name = format!( + "file_deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef_{}.dat", + i + ); + writer.start_file(name, options).unwrap(); + writer.write_all(&bytes).unwrap(); + } + + writer.finish().unwrap().into_inner() +} + +fn read_metadata(bench: &mut Bencher) { + let bytes = generate_random_archive(FILE_COUNT, FILE_SIZE); + + bench.iter(|| { + let archive = ZipArchive::new(Cursor::new(bytes.as_slice())).unwrap(); + archive.len() + }); +} + +benchmark_group!(benches, read_metadata); +benchmark_main!(benches); diff --git a/src/read.rs b/src/read.rs index 0d920032..0c06db17 100644 --- a/src/read.rs +++ b/src/read.rs @@ -408,8 +408,8 @@ impl ZipArchive { let (archive_offset, directory_start, number_of_files) = Self::get_directory_counts(&mut reader, &footer, cde_start_pos)?; - let mut files = Vec::new(); - let mut names_map = HashMap::new(); + let mut files = Vec::with_capacity(number_of_files); + let mut names_map = HashMap::with_capacity(number_of_files); if reader.seek(io::SeekFrom::Start(directory_start)).is_err() { return Err(ZipError::InvalidArchive(