mirror of
https://github.com/Serial-ATA/lofty-rs
synced 2024-12-05 02:19:12 +00:00
benches: Switch to iai_callgrind + Bencher
This commit is contained in:
parent
b110072f84
commit
2f2263378b
4 changed files with 184 additions and 204 deletions
71
.github/workflows/bench.yml
vendored
71
.github/workflows/bench.yml
vendored
|
@ -1,45 +1,34 @@
|
|||
name: Benchmark
|
||||
name: Continuous Benchmarking with Bencher
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- 'src/**'
|
||||
- 'benches/**'
|
||||
- 'ogg_pager/**'
|
||||
branches:
|
||||
- main
|
||||
workflow_dispatch:
|
||||
|
||||
push:
|
||||
paths:
|
||||
- 'src/**'
|
||||
- 'benches/**'
|
||||
- 'ogg_pager/**'
|
||||
branches:
|
||||
- main
|
||||
workflow_dispatch:
|
||||
jobs:
|
||||
benchmark:
|
||||
name: Benchmark
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install Rust toolchain
|
||||
uses: dtolnay/rust-toolchain@v1
|
||||
with:
|
||||
toolchain: nightly
|
||||
|
||||
- name: Run benchmark
|
||||
benchmark_with_bencher:
|
||||
name: Benchmark with Bencher
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
RUSTFLAGS: '--cfg bench'
|
||||
run: |
|
||||
cargo bench --all-features -- --output-format bencher | tee output.txt
|
||||
BENCHER_PROJECT: lofty
|
||||
BENCHER_BRANCH: main
|
||||
BENCHER_API_TOKEN: ${{ secrets.BENCHER_API_TOKEN }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Store benchmark result
|
||||
uses: benchmark-action/github-action-benchmark@v1
|
||||
with:
|
||||
# What benchmark tool the output.txt came from
|
||||
tool: 'cargo'
|
||||
# Where the output from the benchmark tool is stored
|
||||
output-file-path: output.txt
|
||||
# Show alert with commit comment on detecting possible performance regression
|
||||
alert-threshold: '200%'
|
||||
# Workflow will fail when an alert happens
|
||||
fail-on-alert: true
|
||||
# GitHub API token to make a commit comment
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# Enable alert commit comment
|
||||
comment-on-alert: true
|
||||
auto-push: true
|
||||
- name: Install callgrind
|
||||
run: sudo apt-get install -y valgrind
|
||||
- name: Install iai-callgrind-runner
|
||||
run: |
|
||||
version=$(cargo metadata --format-version=1 |\
|
||||
jq '.packages[] | select(.name == "iai-callgrind").version' |\
|
||||
tr -d '"'
|
||||
)
|
||||
cargo install iai-callgrind-runner --version $version
|
||||
- uses: bencherdev/bencher@main
|
||||
- name: Run Bencher
|
||||
run: |
|
||||
bencher run --adapter rust_iai_callgrind --err "cargo bench"
|
||||
|
|
|
@ -36,14 +36,14 @@ hound = { git = "https://github.com/ruuda/hound.git", rev = "02e66effb33683d
|
|||
# tag_writer example
|
||||
structopt = { version = "0.3.26", default-features = false }
|
||||
tempfile = "3.9.0"
|
||||
|
||||
# Pretty heavy dependency, we don't want this compiling for test/doc runs
|
||||
[target.'cfg(bench)'.dev-dependencies]
|
||||
criterion = { version = "0.5.1", features = ["html_reports"] }
|
||||
iai-callgrind = "0.10.2"
|
||||
|
||||
[lib]
|
||||
bench = false
|
||||
|
||||
[profile.bench]
|
||||
debug = true
|
||||
|
||||
[[bench]]
|
||||
name = "read_file"
|
||||
path = "benches/read_file.rs"
|
||||
|
|
|
@ -7,126 +7,120 @@ use lofty::mp4::Ilst;
|
|||
use lofty::ogg::VorbisComments;
|
||||
use lofty::{Accessor, MimeType, Picture, PictureType, TagExt, WriteOptions};
|
||||
|
||||
use criterion::{criterion_group, criterion_main, Criterion};
|
||||
use iai_callgrind::{library_benchmark, library_benchmark_group, main};
|
||||
|
||||
const ENCODER: &str = "Lavf57.56.101";
|
||||
|
||||
macro_rules! bench_tag_write {
|
||||
($c:ident, [$(($NAME:literal, $tag:ty, |$tag_:ident| $extra_block:block)),+ $(,)?]) => {
|
||||
let mut g = $c.benchmark_group("Tag writing");
|
||||
|
||||
([$(($NAME:ident, $tag:ty, |$tag_:ident| $extra_block:block)),+ $(,)?]) => {
|
||||
$(
|
||||
g.bench_function(
|
||||
$NAME,
|
||||
|b| b.iter(|| {
|
||||
let mut v = Vec::new();
|
||||
let mut $tag_ = <$tag>::default();
|
||||
#[library_benchmark]
|
||||
fn $NAME() {
|
||||
let mut v = Vec::new();
|
||||
let mut $tag_ = <$tag>::default();
|
||||
|
||||
$tag_.set_artist(String::from("Dave Eddy"));
|
||||
$tag_.set_title(String::from("TempleOS Hymn Risen (Remix)"));
|
||||
$tag_.set_album(String::from("Summer"));
|
||||
$tag_.set_year(2017);
|
||||
$tag_.set_track(1);
|
||||
$tag_.set_genre(String::from("Electronic"));
|
||||
$extra_block
|
||||
$tag_.dump_to(&mut v, WriteOptions::default()).unwrap();
|
||||
})
|
||||
);
|
||||
$tag_.set_artist(String::from("Dave Eddy"));
|
||||
$tag_.set_title(String::from("TempleOS Hymn Risen (Remix)"));
|
||||
$tag_.set_album(String::from("Summer"));
|
||||
$tag_.set_year(2017);
|
||||
$tag_.set_track(1);
|
||||
$tag_.set_genre(String::from("Electronic"));
|
||||
$extra_block;
|
||||
$tag_.dump_to(&mut v, WriteOptions::default()).unwrap();
|
||||
}
|
||||
)+
|
||||
}
|
||||
}
|
||||
|
||||
fn bench_write(c: &mut Criterion) {
|
||||
bench_tag_write!(
|
||||
c,
|
||||
[
|
||||
("AIFF Text Chunks", AIFFTextChunks, |tag| {}),
|
||||
("APEv2", ApeTag, |tag| {
|
||||
use lofty::ape::ApeItem;
|
||||
use lofty::ItemValue;
|
||||
bench_tag_write!([
|
||||
(aiff_text_chunks, AIFFTextChunks, |tag| {}),
|
||||
(apev2, ApeTag, |tag| {
|
||||
use lofty::ape::ApeItem;
|
||||
use lofty::ItemValue;
|
||||
|
||||
let picture = Picture::new_unchecked(
|
||||
PictureType::CoverFront,
|
||||
Some(MimeType::Jpeg),
|
||||
None,
|
||||
include_bytes!("../benches_assets/cover.jpg").to_vec(),
|
||||
);
|
||||
let picture = Picture::new_unchecked(
|
||||
PictureType::CoverFront,
|
||||
Some(MimeType::Jpeg),
|
||||
None,
|
||||
include_bytes!("../benches_assets/cover.jpg").to_vec(),
|
||||
);
|
||||
|
||||
tag.insert(
|
||||
ApeItem::new(
|
||||
String::from("Cover (Front)"),
|
||||
ItemValue::Binary(picture.as_ape_bytes()),
|
||||
)
|
||||
.unwrap(),
|
||||
);
|
||||
tag.insert(
|
||||
ApeItem::new(
|
||||
String::from("Encoder"),
|
||||
ItemValue::Text(String::from(ENCODER)),
|
||||
)
|
||||
.unwrap(),
|
||||
);
|
||||
}),
|
||||
("ID3v2", Id3v2Tag, |tag| {
|
||||
use lofty::id3::v2::{Frame, FrameFlags, TextInformationFrame};
|
||||
use lofty::TextEncoding;
|
||||
tag.insert(
|
||||
ApeItem::new(
|
||||
String::from("Cover (Front)"),
|
||||
ItemValue::Binary(picture.as_ape_bytes()),
|
||||
)
|
||||
.unwrap(),
|
||||
);
|
||||
tag.insert(
|
||||
ApeItem::new(
|
||||
String::from("Encoder"),
|
||||
ItemValue::Text(String::from(ENCODER)),
|
||||
)
|
||||
.unwrap(),
|
||||
);
|
||||
}),
|
||||
(id3v2, Id3v2Tag, |tag| {
|
||||
use lofty::id3::v2::{Frame, FrameFlags, TextInformationFrame};
|
||||
use lofty::TextEncoding;
|
||||
|
||||
let picture = Picture::new_unchecked(
|
||||
PictureType::CoverFront,
|
||||
Some(MimeType::Jpeg),
|
||||
None,
|
||||
include_bytes!("../benches_assets/cover.jpg").to_vec(),
|
||||
);
|
||||
let picture = Picture::new_unchecked(
|
||||
PictureType::CoverFront,
|
||||
Some(MimeType::Jpeg),
|
||||
None,
|
||||
include_bytes!("../benches_assets/cover.jpg").to_vec(),
|
||||
);
|
||||
|
||||
tag.insert_picture(picture);
|
||||
tag.insert(
|
||||
Frame::new(
|
||||
"TSSE",
|
||||
TextInformationFrame {
|
||||
encoding: TextEncoding::Latin1,
|
||||
value: String::from(ENCODER),
|
||||
},
|
||||
FrameFlags::default(),
|
||||
)
|
||||
.unwrap(),
|
||||
);
|
||||
}),
|
||||
("ID3v1", Id3v1Tag, |tag| {}),
|
||||
("MP4 Ilst", Ilst, |tag| {
|
||||
use lofty::mp4::{Atom, AtomData, AtomIdent};
|
||||
tag.insert_picture(picture);
|
||||
tag.insert(
|
||||
Frame::new(
|
||||
"TSSE",
|
||||
TextInformationFrame {
|
||||
encoding: TextEncoding::Latin1,
|
||||
value: String::from(ENCODER),
|
||||
},
|
||||
FrameFlags::default(),
|
||||
)
|
||||
.unwrap(),
|
||||
);
|
||||
}),
|
||||
(id3v1, Id3v1Tag, |tag| {}),
|
||||
(ilst, Ilst, |tag| {
|
||||
use lofty::mp4::{Atom, AtomData, AtomIdent};
|
||||
|
||||
let picture = Picture::new_unchecked(
|
||||
PictureType::CoverFront,
|
||||
Some(MimeType::Jpeg),
|
||||
None,
|
||||
include_bytes!("../benches_assets/cover.jpg").to_vec(),
|
||||
);
|
||||
let picture = Picture::new_unchecked(
|
||||
PictureType::CoverFront,
|
||||
Some(MimeType::Jpeg),
|
||||
None,
|
||||
include_bytes!("../benches_assets/cover.jpg").to_vec(),
|
||||
);
|
||||
|
||||
tag.insert_picture(picture);
|
||||
tag.insert(Atom::new(
|
||||
AtomIdent::Fourcc(*b"\xa9too"),
|
||||
AtomData::UTF8(String::from(ENCODER)),
|
||||
));
|
||||
}),
|
||||
("RIFF INFO", RIFFInfoList, |tag| {
|
||||
tag.insert(String::from("ISFT"), String::from(ENCODER));
|
||||
}),
|
||||
("Vorbis Comments", VorbisComments, |tag| {
|
||||
use lofty::ogg::OggPictureStorage;
|
||||
tag.insert_picture(picture);
|
||||
tag.insert(Atom::new(
|
||||
AtomIdent::Fourcc(*b"\xa9too"),
|
||||
AtomData::UTF8(String::from(ENCODER)),
|
||||
));
|
||||
}),
|
||||
(riff_info, RIFFInfoList, |tag| {
|
||||
tag.insert(String::from("ISFT"), String::from(ENCODER));
|
||||
}),
|
||||
(vorbis_comments, VorbisComments, |tag| {
|
||||
use lofty::ogg::OggPictureStorage;
|
||||
|
||||
let picture = Picture::new_unchecked(
|
||||
PictureType::CoverFront,
|
||||
Some(MimeType::Jpeg),
|
||||
None,
|
||||
include_bytes!("../benches_assets/cover.jpg").to_vec(),
|
||||
);
|
||||
let picture = Picture::new_unchecked(
|
||||
PictureType::CoverFront,
|
||||
Some(MimeType::Jpeg),
|
||||
None,
|
||||
include_bytes!("../benches_assets/cover.jpg").to_vec(),
|
||||
);
|
||||
|
||||
let _ = tag.insert_picture(picture, None).unwrap();
|
||||
tag.push(String::from("ENCODER"), String::from(ENCODER));
|
||||
}),
|
||||
]
|
||||
);
|
||||
}
|
||||
let _ = tag.insert_picture(picture, None).unwrap();
|
||||
tag.push(String::from("ENCODER"), String::from(ENCODER));
|
||||
}),
|
||||
]);
|
||||
|
||||
criterion_group!(benches, bench_write);
|
||||
criterion_main!(benches);
|
||||
library_benchmark_group!(
|
||||
name = tag_writing;
|
||||
benchmarks = aiff_text_chunks, apev2, id3v2, id3v1, ilst, riff_info, vorbis_comments
|
||||
);
|
||||
main!(library_benchmark_groups = tag_writing);
|
||||
|
|
|
@ -1,68 +1,65 @@
|
|||
use lofty::{ParseOptions, Probe};
|
||||
|
||||
use criterion::{criterion_group, criterion_main, Criterion};
|
||||
use iai_callgrind::{library_benchmark, library_benchmark_group, main};
|
||||
|
||||
use std::hint::black_box;
|
||||
use std::io::Cursor;
|
||||
|
||||
macro_rules! test_read_file {
|
||||
($c:ident, [$(($NAME:ident, $path:expr)),+ $(,)?]) => {
|
||||
let mut g = $c.benchmark_group("File reading (Inferred from Content)");
|
||||
|
||||
([$(($NAME:ident, $path:expr)),+ $(,)?]) => {
|
||||
$(
|
||||
const $NAME: &[u8] = include_bytes!($path);
|
||||
paste::paste! {
|
||||
#[library_benchmark]
|
||||
fn [<$NAME:lower>]() {
|
||||
const $NAME: &[u8] = include_bytes!($path);
|
||||
|
||||
g.bench_function(
|
||||
stringify!($NAME),
|
||||
|b| b.iter(|| {
|
||||
Probe::new(Cursor::new($NAME))
|
||||
.options(ParseOptions::new())
|
||||
.guess_file_type()
|
||||
.unwrap()
|
||||
.read()
|
||||
.unwrap()
|
||||
})
|
||||
);
|
||||
black_box(Probe::new(Cursor::new($NAME))
|
||||
.options(ParseOptions::new())
|
||||
.guess_file_type()
|
||||
.unwrap()
|
||||
.read()
|
||||
.unwrap());
|
||||
}
|
||||
}
|
||||
)+
|
||||
}
|
||||
}
|
||||
|
||||
fn content_infer_read(c: &mut Criterion) {
|
||||
test_read_file!(
|
||||
c,
|
||||
[
|
||||
(AAC, "../benches_assets/01 TempleOS Hymn Risen (Remix).aac"),
|
||||
(
|
||||
AIFF,
|
||||
"../benches_assets/01 TempleOS Hymn Risen (Remix).aiff"
|
||||
),
|
||||
(APE, "../benches_assets/01 TempleOS Hymn Risen (Remix).ape"),
|
||||
(
|
||||
FLAC,
|
||||
"../benches_assets/01 TempleOS Hymn Risen (Remix).flac"
|
||||
),
|
||||
(MP4, "../benches_assets/01 TempleOS Hymn Risen (Remix).m4a"),
|
||||
(MP3, "../benches_assets/01 TempleOS Hymn Risen (Remix).mp3"),
|
||||
(MPC, "../benches_assets/01 TempleOS Hymn Risen (Remix).mpc"),
|
||||
(
|
||||
OPUS,
|
||||
"../benches_assets/01 TempleOS Hymn Risen (Remix).opus"
|
||||
),
|
||||
(RIFF, "../benches_assets/01 TempleOS Hymn Risen (Remix).wav"),
|
||||
(
|
||||
SPEEX,
|
||||
"../benches_assets/01 TempleOS Hymn Risen (Remix).spx"
|
||||
),
|
||||
(
|
||||
VORBIS,
|
||||
"../benches_assets/01 TempleOS Hymn Risen (Remix).ogg"
|
||||
),
|
||||
(
|
||||
WAVPACK,
|
||||
"../benches_assets/01 TempleOS Hymn Risen (Remix).wv"
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
test_read_file!([
|
||||
(AAC, "../benches_assets/01 TempleOS Hymn Risen (Remix).aac"),
|
||||
(
|
||||
AIFF,
|
||||
"../benches_assets/01 TempleOS Hymn Risen (Remix).aiff"
|
||||
),
|
||||
(APE, "../benches_assets/01 TempleOS Hymn Risen (Remix).ape"),
|
||||
(
|
||||
FLAC,
|
||||
"../benches_assets/01 TempleOS Hymn Risen (Remix).flac"
|
||||
),
|
||||
(MP4, "../benches_assets/01 TempleOS Hymn Risen (Remix).m4a"),
|
||||
(MP3, "../benches_assets/01 TempleOS Hymn Risen (Remix).mp3"),
|
||||
(MPC, "../benches_assets/01 TempleOS Hymn Risen (Remix).mpc"),
|
||||
(
|
||||
OPUS,
|
||||
"../benches_assets/01 TempleOS Hymn Risen (Remix).opus"
|
||||
),
|
||||
(RIFF, "../benches_assets/01 TempleOS Hymn Risen (Remix).wav"),
|
||||
(
|
||||
SPEEX,
|
||||
"../benches_assets/01 TempleOS Hymn Risen (Remix).spx"
|
||||
),
|
||||
(
|
||||
VORBIS,
|
||||
"../benches_assets/01 TempleOS Hymn Risen (Remix).ogg"
|
||||
),
|
||||
(
|
||||
WAVPACK,
|
||||
"../benches_assets/01 TempleOS Hymn Risen (Remix).wv"
|
||||
),
|
||||
]);
|
||||
|
||||
criterion_group!(benches, content_infer_read);
|
||||
criterion_main!(benches);
|
||||
library_benchmark_group!(
|
||||
name = file_reading;
|
||||
benchmarks = aac, aiff, ape, flac, mp4, mp3, mpc, opus, riff, speex, vorbis, wavpack
|
||||
);
|
||||
main!(library_benchmark_groups = file_reading);
|
||||
|
|
Loading…
Reference in a new issue