Skip to content

Commit

Permalink
Benchmark of next_row-based decoding.
Browse files Browse the repository at this point in the history
  • Loading branch information
anforowicz committed Jul 17, 2024
1 parent 2cfde02 commit b7d0c06
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 10 deletions.
46 changes: 36 additions & 10 deletions benches/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ fn load_all(c: &mut Criterion) {
bench_noncompressed_png(&mut g, 2048, 0x7fffffff); // 16 MB
bench_noncompressed_png(&mut g, 12288, 0x7fffffff); // 576 MB
g.finish();

// Incremental decoding via `next_row`
let mut g = c.benchmark_group("row-by-row");
let mut data = Vec::new();
test_utils::write_noncompressed_png(&mut data, 128, 4096);
bench_next_row(&mut g, data, "128x128-4k-idat");
g.finish();
}

criterion_group! {benches, load_all}
Expand All @@ -52,21 +59,12 @@ fn bench_noncompressed_png(g: &mut BenchmarkGroup<WallTime>, size: u32, idat_byt
bench_file(g, data, format!("{size}x{size}.png"));
}

/// This benchmarks decoding via a call to `Reader::next_frame`.
fn bench_file(g: &mut BenchmarkGroup<WallTime>, data: Vec<u8>, name: String) {
if data.len() > 1_000_000 {
g.sample_size(10);
}

fn create_reader(data: &[u8]) -> Reader<&[u8]> {
let mut decoder = Decoder::new(data);

// Cover default transformations used by the `image` crate when constructing
// `image::codecs::png::PngDecoder`.
decoder.set_transformations(Transformations::EXPAND);

decoder.read_info().unwrap()
}

let mut reader = create_reader(data.as_slice());
let mut image = vec![0; reader.output_buffer_size()];
let info = reader.next_frame(&mut image).unwrap();
Expand All @@ -79,3 +77,31 @@ fn bench_file(g: &mut BenchmarkGroup<WallTime>, data: Vec<u8>, name: String) {
})
});
}

/// This benchmarks decoding via a sequence of `Reader::next_row` calls.
fn bench_next_row(g: &mut BenchmarkGroup<WallTime>, data: Vec<u8>, name: &str) {
let reader = create_reader(data.as_slice());
let mut image = vec![0; reader.output_buffer_size()];
let bytes_per_row = reader.output_line_size(reader.info().width);
g.throughput(Throughput::Bytes(image.len() as u64));
g.bench_with_input(name, &data, |b, data| {
b.iter(|| {
let mut reader = create_reader(data.as_slice());

for output_row in image.chunks_exact_mut(bytes_per_row) {
let decoded_row = reader.next_row().unwrap().unwrap();
output_row.copy_from_slice(decoded_row.data());
}
})
});
}

fn create_reader(data: &[u8]) -> Reader<&[u8]> {
let mut decoder = Decoder::new(data);

// Cover default transformations used by the `image` crate when constructing
// `image::codecs::png::PngDecoder`.
decoder.set_transformations(Transformations::EXPAND);

decoder.read_info().unwrap()
}
1 change: 1 addition & 0 deletions src/decoder/stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ pub const CHUNK_BUFFER_SIZE: usize = 32 * 1024;
///
/// This is used only in fuzzing. `afl` automatically adds `--cfg fuzzing` to RUSTFLAGS which can
/// be used to detect that build.
#[allow(unexpected_cfgs)]
const CHECKSUM_DISABLED: bool = cfg!(fuzzing);

/// Kind of `u32` value that is being read via `State::U32`.
Expand Down

0 comments on commit b7d0c06

Please sign in to comment.