Fix benches

This commit is contained in:
Andrew 2022-10-24 14:34:27 +13:00
parent 3e34111ebf
commit 55e5c03a87
3 changed files with 231 additions and 282 deletions

View file

@ -7,7 +7,6 @@ use std::path::PathBuf;
use test::Bencher; use test::Bencher;
use oxipng::internal_tests::*; use oxipng::internal_tests::*;
use oxipng::Deadline;
#[bench] #[bench]
fn deflate_16_bits_strategy_0(b: &mut Bencher) { fn deflate_16_bits_strategy_0(b: &mut Bencher) {
@ -16,7 +15,7 @@ fn deflate_16_bits_strategy_0(b: &mut Bencher) {
b.iter(|| { b.iter(|| {
let min = AtomicMin::new(None); let min = AtomicMin::new(None);
deflate(png.raw.data.as_ref(), 9, 0, 15, &min, &Deadline::new(None)) deflate(png.raw.data.as_ref(), 12, &min)
}); });
} }
@ -27,7 +26,7 @@ fn deflate_8_bits_strategy_0(b: &mut Bencher) {
b.iter(|| { b.iter(|| {
let min = AtomicMin::new(None); let min = AtomicMin::new(None);
deflate(png.raw.data.as_ref(), 9, 0, 15, &min, &Deadline::new(None)) deflate(png.raw.data.as_ref(), 12, &min)
}); });
} }
@ -40,7 +39,7 @@ fn deflate_4_bits_strategy_0(b: &mut Bencher) {
b.iter(|| { b.iter(|| {
let min = AtomicMin::new(None); let min = AtomicMin::new(None);
deflate(png.raw.data.as_ref(), 9, 0, 15, &min, &Deadline::new(None)) deflate(png.raw.data.as_ref(), 12, &min)
}); });
} }
@ -53,7 +52,7 @@ fn deflate_2_bits_strategy_0(b: &mut Bencher) {
b.iter(|| { b.iter(|| {
let min = AtomicMin::new(None); let min = AtomicMin::new(None);
deflate(png.raw.data.as_ref(), 9, 0, 15, &min, &Deadline::new(None)) deflate(png.raw.data.as_ref(), 12, &min)
}); });
} }
@ -66,7 +65,7 @@ fn deflate_1_bits_strategy_0(b: &mut Bencher) {
b.iter(|| { b.iter(|| {
let min = AtomicMin::new(None); let min = AtomicMin::new(None);
deflate(png.raw.data.as_ref(), 9, 0, 15, &min, &Deadline::new(None)) deflate(png.raw.data.as_ref(), 12, &min)
}); });
} }
@ -77,7 +76,7 @@ fn deflate_16_bits_strategy_1(b: &mut Bencher) {
b.iter(|| { b.iter(|| {
let min = AtomicMin::new(None); let min = AtomicMin::new(None);
deflate(png.raw.data.as_ref(), 9, 1, 15, &min, &Deadline::new(None)) deflate(png.raw.data.as_ref(), 12, &min)
}); });
} }
@ -88,7 +87,7 @@ fn deflate_8_bits_strategy_1(b: &mut Bencher) {
b.iter(|| { b.iter(|| {
let min = AtomicMin::new(None); let min = AtomicMin::new(None);
deflate(png.raw.data.as_ref(), 9, 1, 15, &min, &Deadline::new(None)) deflate(png.raw.data.as_ref(), 12, &min)
}); });
} }
@ -101,7 +100,7 @@ fn deflate_4_bits_strategy_1(b: &mut Bencher) {
b.iter(|| { b.iter(|| {
let min = AtomicMin::new(None); let min = AtomicMin::new(None);
deflate(png.raw.data.as_ref(), 9, 1, 15, &min, &Deadline::new(None)) deflate(png.raw.data.as_ref(), 12, &min)
}); });
} }
@ -114,7 +113,7 @@ fn deflate_2_bits_strategy_1(b: &mut Bencher) {
b.iter(|| { b.iter(|| {
let min = AtomicMin::new(None); let min = AtomicMin::new(None);
deflate(png.raw.data.as_ref(), 9, 1, 15, &min, &Deadline::new(None)) deflate(png.raw.data.as_ref(), 12, &min)
}); });
} }
@ -127,7 +126,7 @@ fn deflate_1_bits_strategy_1(b: &mut Bencher) {
b.iter(|| { b.iter(|| {
let min = AtomicMin::new(None); let min = AtomicMin::new(None);
deflate(png.raw.data.as_ref(), 9, 1, 15, &min, &Deadline::new(None)) deflate(png.raw.data.as_ref(), 12, &min)
}); });
} }
@ -138,7 +137,7 @@ fn deflate_16_bits_strategy_2(b: &mut Bencher) {
b.iter(|| { b.iter(|| {
let min = AtomicMin::new(None); let min = AtomicMin::new(None);
deflate(png.raw.data.as_ref(), 9, 2, 15, &min, &Deadline::new(None)) deflate(png.raw.data.as_ref(), 12, &min)
}); });
} }
@ -149,7 +148,7 @@ fn deflate_8_bits_strategy_2(b: &mut Bencher) {
b.iter(|| { b.iter(|| {
let min = AtomicMin::new(None); let min = AtomicMin::new(None);
deflate(png.raw.data.as_ref(), 9, 2, 15, &min, &Deadline::new(None)) deflate(png.raw.data.as_ref(), 12, &min)
}); });
} }
@ -162,7 +161,7 @@ fn deflate_4_bits_strategy_2(b: &mut Bencher) {
b.iter(|| { b.iter(|| {
let min = AtomicMin::new(None); let min = AtomicMin::new(None);
deflate(png.raw.data.as_ref(), 9, 2, 15, &min, &Deadline::new(None)) deflate(png.raw.data.as_ref(), 12, &min)
}); });
} }
@ -175,7 +174,7 @@ fn deflate_2_bits_strategy_2(b: &mut Bencher) {
b.iter(|| { b.iter(|| {
let min = AtomicMin::new(None); let min = AtomicMin::new(None);
deflate(png.raw.data.as_ref(), 9, 2, 15, &min, &Deadline::new(None)) deflate(png.raw.data.as_ref(), 12, &min)
}); });
} }
@ -188,7 +187,7 @@ fn deflate_1_bits_strategy_2(b: &mut Bencher) {
b.iter(|| { b.iter(|| {
let min = AtomicMin::new(None); let min = AtomicMin::new(None);
deflate(png.raw.data.as_ref(), 9, 2, 15, &min, &Deadline::new(None)) deflate(png.raw.data.as_ref(), 12, &min)
}); });
} }
@ -199,7 +198,7 @@ fn deflate_16_bits_strategy_3(b: &mut Bencher) {
b.iter(|| { b.iter(|| {
let min = AtomicMin::new(None); let min = AtomicMin::new(None);
deflate(png.raw.data.as_ref(), 9, 3, 15, &min, &Deadline::new(None)) deflate(png.raw.data.as_ref(), 12, &min)
}); });
} }
@ -210,7 +209,7 @@ fn deflate_8_bits_strategy_3(b: &mut Bencher) {
b.iter(|| { b.iter(|| {
let min = AtomicMin::new(None); let min = AtomicMin::new(None);
deflate(png.raw.data.as_ref(), 9, 3, 15, &min, &Deadline::new(None)) deflate(png.raw.data.as_ref(), 12, &min)
}); });
} }
@ -223,7 +222,7 @@ fn deflate_4_bits_strategy_3(b: &mut Bencher) {
b.iter(|| { b.iter(|| {
let min = AtomicMin::new(None); let min = AtomicMin::new(None);
deflate(png.raw.data.as_ref(), 9, 3, 15, &min, &Deadline::new(None)) deflate(png.raw.data.as_ref(), 12, &min)
}); });
} }
@ -236,7 +235,7 @@ fn deflate_2_bits_strategy_3(b: &mut Bencher) {
b.iter(|| { b.iter(|| {
let min = AtomicMin::new(None); let min = AtomicMin::new(None);
deflate(png.raw.data.as_ref(), 9, 3, 15, &min, &Deadline::new(None)) deflate(png.raw.data.as_ref(), 12, &min)
}); });
} }
@ -249,7 +248,7 @@ fn deflate_1_bits_strategy_3(b: &mut Bencher) {
b.iter(|| { b.iter(|| {
let min = AtomicMin::new(None); let min = AtomicMin::new(None);
deflate(png.raw.data.as_ref(), 9, 3, 15, &min, &Deadline::new(None)) deflate(png.raw.data.as_ref(), 12, &min)
}); });
} }
@ -258,5 +257,5 @@ fn inflate_generic(b: &mut Bencher) {
let input = test::black_box(PathBuf::from("tests/files/rgb_16_should_be_rgb_16.png")); let input = test::black_box(PathBuf::from("tests/files/rgb_16_should_be_rgb_16.png"));
let png = PngData::new(&input, false).unwrap(); let png = PngData::new(&input, false).unwrap();
b.iter(|| inflate(png.idat_data.as_ref())); b.iter(|| inflate(png.idat_data.as_ref(), png.raw.ihdr.raw_data_size()));
} }

View file

@ -1,64 +0,0 @@
#![feature(test)]
extern crate oxipng;
extern crate test;
use oxipng::internal_tests::*;
use std::path::PathBuf;
use test::Bencher;
#[bench]
fn libdeflater_16_bits_strategy_0(b: &mut Bencher) {
let input = test::black_box(PathBuf::from("tests/files/rgb_16_should_be_rgb_16.png"));
let png = PngData::new(&input, false).unwrap();
b.iter(|| {
libdeflater_deflate(png.raw.data.as_ref(), 12, &AtomicMin::new(None)).ok();
});
}
#[bench]
fn libdeflater_8_bits_strategy_0(b: &mut Bencher) {
let input = test::black_box(PathBuf::from("tests/files/rgb_8_should_be_rgb_8.png"));
let png = PngData::new(&input, false).unwrap();
b.iter(|| {
libdeflater_deflate(png.raw.data.as_ref(), 12, &AtomicMin::new(None)).ok();
});
}
#[bench]
fn libdeflater_4_bits_strategy_0(b: &mut Bencher) {
let input = test::black_box(PathBuf::from(
"tests/files/palette_4_should_be_palette_4.png",
));
let png = PngData::new(&input, false).unwrap();
b.iter(|| {
libdeflater_deflate(png.raw.data.as_ref(), 12, &AtomicMin::new(None)).ok();
});
}
#[bench]
fn libdeflater_2_bits_strategy_0(b: &mut Bencher) {
let input = test::black_box(PathBuf::from(
"tests/files/palette_2_should_be_palette_2.png",
));
let png = PngData::new(&input, false).unwrap();
b.iter(|| {
libdeflater_deflate(png.raw.data.as_ref(), 12, &AtomicMin::new(None)).ok();
});
}
#[bench]
fn libdeflater_1_bits_strategy_0(b: &mut Bencher) {
let input = test::black_box(PathBuf::from(
"tests/files/palette_1_should_be_palette_1.png",
));
let png = PngData::new(&input, false).unwrap();
b.iter(|| {
libdeflater_deflate(png.raw.data.as_ref(), 12, &AtomicMin::new(None)).ok();
});
}

View file

@ -33,13 +33,16 @@ fn main() {
.author("Joshua Holmer <jholmer.in@gmail.com>") .author("Joshua Holmer <jholmer.in@gmail.com>")
.about("Losslessly improves compression of PNG files") .about("Losslessly improves compression of PNG files")
.setting(AppSettings::DeriveDisplayOrder) .setting(AppSettings::DeriveDisplayOrder)
.arg(Arg::new("files") .arg(
Arg::new("files")
.help("File(s) to compress (use \"-\" for stdin)") .help("File(s) to compress (use \"-\" for stdin)")
.index(1) .index(1)
.multiple_values(true) .multiple_values(true)
.use_value_delimiter(false) .use_value_delimiter(false)
.required(true)) .required(true),
.arg(Arg::new("optimization") )
.arg(
Arg::new("optimization")
.help("Optimization level - Default: 2") .help("Optimization level - Default: 2")
.short('o') .short('o')
.long("opt") .long("opt")
@ -52,183 +55,192 @@ fn main() {
.possible_value("4") .possible_value("4")
.possible_value("5") .possible_value("5")
.possible_value("6") .possible_value("6")
.possible_value("max")) .possible_value("max"),
.arg(Arg::new("backup") )
.arg(
Arg::new("backup")
.help("Back up modified files") .help("Back up modified files")
.short('b') .short('b')
.long("backup")) .long("backup"),
.arg(Arg::new("recursive") )
.arg(
Arg::new("recursive")
.help("Recurse into subdirectories") .help("Recurse into subdirectories")
.short('r') .short('r')
.long("recursive")) .long("recursive"),
.arg(Arg::new("output_dir") )
.arg(
Arg::new("output_dir")
.help("Write output file(s) to <directory>") .help("Write output file(s) to <directory>")
.long("dir") .long("dir")
.takes_value(true) .takes_value(true)
.value_name("directory") .value_name("directory")
.conflicts_with("output_file") .conflicts_with("output_file")
.conflicts_with("stdout")) .conflicts_with("stdout"),
.arg(Arg::new("output_file") )
.arg(
Arg::new("output_file")
.help("Write output file to <file>") .help("Write output file to <file>")
.long("out") .long("out")
.takes_value(true) .takes_value(true)
.value_name("file") .value_name("file")
.conflicts_with("output_dir") .conflicts_with("output_dir")
.conflicts_with("stdout")) .conflicts_with("stdout"),
.arg(Arg::new("stdout") )
.arg(
Arg::new("stdout")
.help("Write output to stdout") .help("Write output to stdout")
.long("stdout") .long("stdout")
.conflicts_with("output_dir") .conflicts_with("output_dir")
.conflicts_with("output_file")) .conflicts_with("output_file"),
.arg(Arg::new("preserve") )
.arg(
Arg::new("preserve")
.help("Preserve file attributes if possible") .help("Preserve file attributes if possible")
.short('p') .short('p')
.long("preserve")) .long("preserve"),
.arg(Arg::new("check") )
.arg(
Arg::new("check")
.help("Do not run any optimization passes") .help("Do not run any optimization passes")
.short('c') .short('c')
.long("check")) .long("check"),
.arg(Arg::new("pretend") )
.arg(
Arg::new("pretend")
.help("Do not write any files, only calculate compression gains") .help("Do not write any files, only calculate compression gains")
.short('P') .short('P')
.long("pretend")) .long("pretend"),
.arg(Arg::new("strip-safe") )
.arg(
Arg::new("strip-safe")
.help("Strip safely-removable metadata objects") .help("Strip safely-removable metadata objects")
.short('s') .short('s')
.conflicts_with("strip")) .conflicts_with("strip"),
.arg(Arg::new("strip") )
.arg(
Arg::new("strip")
.help("Strip metadata objects ['safe', 'all', or comma-separated list]") .help("Strip metadata objects ['safe', 'all', or comma-separated list]")
.long("strip") .long("strip")
.takes_value(true) .takes_value(true)
.value_name("mode") .value_name("mode")
.conflicts_with("strip-safe")) .conflicts_with("strip-safe"),
.arg(Arg::new("keep") )
.arg(
Arg::new("keep")
.help("Strip all optional metadata except objects in the comma-separated list") .help("Strip all optional metadata except objects in the comma-separated list")
.long("keep") .long("keep")
.takes_value(true) .takes_value(true)
.value_name("list") .value_name("list")
.conflicts_with("strip") .conflicts_with("strip")
.conflicts_with("strip-safe")) .conflicts_with("strip-safe"),
.arg(Arg::new("alpha") )
.arg(
Arg::new("alpha")
.help("Perform additional alpha optimizations") .help("Perform additional alpha optimizations")
.short('a') .short('a')
.long("alpha")) .long("alpha"),
.arg(Arg::new("interlace") )
.arg(
Arg::new("interlace")
.help("PNG interlace type") .help("PNG interlace type")
.short('i') .short('i')
.long("interlace") .long("interlace")
.takes_value(true) .takes_value(true)
.value_name("0/1") .value_name("0/1")
.possible_value("0") .possible_value("0")
.possible_value("1")) .possible_value("1"),
.arg(Arg::new("verbose") )
.arg(
Arg::new("verbose")
.help("Run in verbose mode") .help("Run in verbose mode")
.short('v') .short('v')
.long("verbose") .long("verbose")
.conflicts_with("quiet")) .conflicts_with("quiet"),
.arg(Arg::new("quiet") )
.arg(
Arg::new("quiet")
.help("Run in quiet mode") .help("Run in quiet mode")
.short('q') .short('q')
.long("quiet") .long("quiet")
.conflicts_with("verbose")) .conflicts_with("verbose"),
.arg(Arg::new("filters") )
.arg(
Arg::new("filters")
.help("PNG delta filters (0-5) - Default: 0,5") .help("PNG delta filters (0-5) - Default: 0,5")
.short('f') .short('f')
.long("filters") .long("filters")
.takes_value(true) .takes_value(true)
.validator(|x| { .validator(|x| match parse_numeric_range_opts(x, 0, 5) {
match parse_numeric_range_opts(x, 0, 5) {
Ok(_) => Ok(()), Ok(_) => Ok(()),
Err(_) => Err("Invalid option for filters".to_owned()), Err(_) => Err("Invalid option for filters".to_owned()),
} }),
})) )
.arg(Arg::new("compression") .arg(
Arg::new("compression")
.help("zlib compression levels (1-12) - Default: 12") .help("zlib compression levels (1-12) - Default: 12")
.long("zc") .long("zc")
.takes_value(true) .takes_value(true)
.value_name("levels") .value_name("levels")
.validator(|x| { .validator(|x| match parse_numeric_range_opts(x, 1, 12) {
match parse_numeric_range_opts(x, 1, 12) {
Ok(_) => Ok(()), Ok(_) => Ok(()),
Err(_) => Err("Invalid option for compression".to_owned()), Err(_) => Err("Invalid option for compression".to_owned()),
}
}) })
.conflicts_with_all(&["zopfli", "libdeflater"])) .conflicts_with("zopfli"),
.arg(Arg::new("strategies") )
.help("zlib compression strategies (0-3) - Default: 0-3") .arg(
.long("zs") Arg::new("no-bit-reduction")
.takes_value(true)
.validator(|x| {
match parse_numeric_range_opts(x, 0, 3) {
Ok(_) => Ok(()),
Err(_) => Err("Invalid option for strategies".to_owned()),
}
})
.hide(true)
.conflicts_with_all(&["zopfli", "libdeflater"]))
.arg(Arg::new("window")
.help("zlib window size - Default: 32k")
.long("zw")
.takes_value(true)
.value_name("size")
.possible_value("256")
.possible_value("512")
.possible_value("1k")
.possible_value("2k")
.possible_value("4k")
.possible_value("8k")
.possible_value("16k")
.possible_value("32k")
.hide(true)
.conflicts_with_all(&["zopfli", "libdeflater"]))
.arg(Arg::new("no-bit-reduction")
.help("No bit depth reduction") .help("No bit depth reduction")
.long("nb")) .long("nb"),
.arg(Arg::new("no-color-reduction") )
.arg(
Arg::new("no-color-reduction")
.help("No color type reduction") .help("No color type reduction")
.long("nc")) .long("nc"),
.arg(Arg::new("no-palette-reduction") )
.arg(
Arg::new("no-palette-reduction")
.help("No palette reduction") .help("No palette reduction")
.long("np")) .long("np"),
.arg(Arg::new("no-grayscale-reduction") )
.arg(
Arg::new("no-grayscale-reduction")
.help("No grayscale reduction") .help("No grayscale reduction")
.long("ng")) .long("ng"),
.arg(Arg::new("no-reductions") )
.help("No reductions") .arg(Arg::new("no-reductions").help("No reductions").long("nx"))
.long("nx")) .arg(
.arg(Arg::new("no-recoding") Arg::new("no-recoding")
.help("No IDAT recoding unless necessary") .help("No IDAT recoding unless necessary")
.long("nz")) .long("nz"),
.arg(Arg::new("fix") )
.help("Enable error recovery") .arg(Arg::new("fix").help("Enable error recovery").long("fix"))
.long("fix")) .arg(
.arg(Arg::new("force") Arg::new("force")
.help("Write the output even if it is larger than the input") .help("Write the output even if it is larger than the input")
.long("force")) .long("force"),
.arg(Arg::new("zopfli") )
.arg(
Arg::new("zopfli")
.help("Use the slower but better compressing Zopfli algorithm") .help("Use the slower but better compressing Zopfli algorithm")
.short('Z') .short('Z')
.long("zopfli") .long("zopfli"),
.conflicts_with("libdeflater")) )
.arg(Arg::new("libdeflater") .arg(
.help("Use an alternative Libdeflater algorithm, overrides zlib-specific options") Arg::new("timeout")
.short('D')
.long("libdeflater")
.hide(true)
.conflicts_with("zopfli"))
.arg(Arg::new("timeout")
.help("Maximum amount of time, in seconds, to spend on optimizations") .help("Maximum amount of time, in seconds, to spend on optimizations")
.takes_value(true) .takes_value(true)
.value_name("secs") .value_name("secs")
.long("timeout")) .long("timeout"),
.arg(Arg::new("threads") )
.arg(
Arg::new("threads")
.help("Set number of threads to use - default 1.5x CPU cores") .help("Set number of threads to use - default 1.5x CPU cores")
.long("threads") .long("threads")
.short('t') .short('t')
.takes_value(true) .takes_value(true)
.value_name("num") .value_name("num")
.validator(|x| { .validator(|x| match x.parse::<usize>() {
match x.parse::<usize>() {
Ok(val) => { Ok(val) => {
if val > 0 { if val > 0 {
Ok(()) Ok(())
@ -237,9 +249,10 @@ fn main() {
} }
} }
Err(_) => Err("Thread count must be >= 1".to_owned()), Err(_) => Err("Thread count must be >= 1".to_owned()),
} }),
})) )
.after_help("Optimization levels: .after_help(
"Optimization levels:
-o 0 => --zc 6 --nz (0 or 1 trials) -o 0 => --zc 6 --nz (0 or 1 trials)
-o 1 => --zc 10 (1 trial, determined heuristically) -o 1 => --zc 10 (1 trial, determined heuristically)
-o 2 => --zc 11 -f 0,5 (2 trials) -o 2 => --zc 11 -f 0,5 (2 trials)
@ -250,7 +263,8 @@ fn main() {
-o max => (stable alias for the max compression) -o max => (stable alias for the max compression)
Manually specifying a compression option (zc, f, etc.) will override the optimization preset, Manually specifying a compression option (zc, f, etc.) will override the optimization preset,
regardless of the order you write the arguments.") regardless of the order you write the arguments.",
)
.get_matches_from(wild::args()); .get_matches_from(wild::args());
let (out_file, out_dir, opts) = match parse_opts_into_struct(&matches) { let (out_file, out_dir, opts) = match parse_opts_into_struct(&matches) {