Skip to content

Commit e34fdea

Browse files
authored
Merge pull request #1571 from lqd/suffix-filtering
Allow excluding benchmarks with suffix
2 parents 0bacca1 + 88112a5 commit e34fdea

File tree

3 files changed

+43
-15
lines changed

3 files changed

+43
-15
lines changed

collector/README.md

+5
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,11 @@ The following options alter the behaviour of the `bench_local` subcommand.
120120
argument is a comma-separated list of benchmark prefixes. When this option is
121121
specified, a benchmark is excluded from the run if its name matches one of
122122
the given prefixes.
123+
- `--exclude-suffix <EXCLUDE>`: this is used to run a subset of the benchmarks. The
124+
argument is a comma-separated list of benchmark suffixes. When this option is
125+
specified, a benchmark is excluded from the run if its name matches one of
126+
the given suffixes. This can be useful to quickly exclude the benchmarks
127+
dedicated to artifact sizes (ending with `-tiny`).
123128
- `--id <ID>` the identifier that will be used to identify the results in the
124129
database.
125130
- `--include <INCLUDE>`: the inverse of `--exclude`. The argument is a

collector/src/benchmark/mod.rs

+30-14
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,7 @@ pub fn get_compile_benchmarks(
371371
benchmark_dir: &Path,
372372
include: Option<&str>,
373373
exclude: Option<&str>,
374+
exclude_suffix: Option<&str>,
374375
) -> anyhow::Result<Vec<Benchmark>> {
375376
let mut benchmarks = Vec::new();
376377

@@ -405,25 +406,23 @@ pub fn get_compile_benchmarks(
405406

406407
let mut includes = to_hashmap(include);
407408
let mut excludes = to_hashmap(exclude);
409+
let mut exclude_suffixes = to_hashmap(exclude_suffix);
408410

409411
for (path, name) in paths {
410412
let mut skip = false;
411413

412-
let name_matches = |prefixes: &mut HashMap<&str, usize>| {
413-
for (prefix, n) in prefixes.iter_mut() {
414-
if name.as_str().starts_with(prefix) {
415-
*n += 1;
416-
return true;
417-
}
418-
}
419-
false
414+
let name_matches_prefix = |prefixes: &mut HashMap<&str, usize>| {
415+
substring_matches(prefixes, |prefix| name.starts_with(prefix))
420416
};
421417

422418
if let Some(includes) = includes.as_mut() {
423-
skip |= !name_matches(includes);
419+
skip |= !name_matches_prefix(includes);
424420
}
425421
if let Some(excludes) = excludes.as_mut() {
426-
skip |= name_matches(excludes);
422+
skip |= name_matches_prefix(excludes);
423+
}
424+
if let Some(exclude_suffixes) = exclude_suffixes.as_mut() {
425+
skip |= substring_matches(exclude_suffixes, |suffix| name.ends_with(suffix));
427426
}
428427
if skip {
429428
continue;
@@ -433,10 +432,10 @@ pub fn get_compile_benchmarks(
433432
benchmarks.push(Benchmark::new(name, path)?);
434433
}
435434

436-
// All prefixes must be used at least once. This is to catch typos.
437-
let check_for_unused = |option, prefixes: Option<HashMap<&str, usize>>| {
438-
if let Some(prefixes) = prefixes {
439-
let unused: Vec<_> = prefixes
435+
// All prefixes/suffixes must be used at least once. This is to catch typos.
436+
let check_for_unused = |option, substrings: Option<HashMap<&str, usize>>| {
437+
if let Some(substrings) = substrings {
438+
let unused: Vec<_> = substrings
440439
.into_iter()
441440
.filter_map(|(i, n)| if n == 0 { Some(i) } else { None })
442441
.collect();
@@ -453,6 +452,7 @@ pub fn get_compile_benchmarks(
453452

454453
check_for_unused("include", includes)?;
455454
check_for_unused("exclude", excludes)?;
455+
check_for_unused("exclude-suffix", exclude_suffixes)?;
456456

457457
benchmarks.sort_by_key(|benchmark| benchmark.name.clone());
458458

@@ -462,3 +462,19 @@ pub fn get_compile_benchmarks(
462462

463463
Ok(benchmarks)
464464
}
465+
466+
/// Helper to verify if a benchmark name matches a given substring, like a prefix or a suffix. The
467+
/// `predicate` closure will be passed each substring from `substrings` until it returns true, and
468+
/// in that case the substring's number of uses in the map will be increased.
469+
fn substring_matches(
470+
substrings: &mut HashMap<&str, usize>,
471+
predicate: impl Fn(&str) -> bool,
472+
) -> bool {
473+
for (substring, n) in substrings.iter_mut() {
474+
if predicate(substring) {
475+
*n += 1;
476+
return true;
477+
}
478+
}
479+
false
480+
}

collector/src/bin/collector.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,10 @@ struct LocalOptions {
512512
#[arg(long)]
513513
exclude: Option<String>,
514514

515+
/// Exclude all benchmarks matching a suffix in this comma-separated list
516+
#[arg(long)]
517+
exclude_suffix: Option<String>,
518+
515519
/// Include only benchmarks matching a prefix in this comma-separated list
516520
#[arg(long)]
517521
include: Option<String>,
@@ -766,6 +770,7 @@ fn main_result() -> anyhow::Result<i32> {
766770
&compile_benchmark_dir,
767771
local.include.as_deref(),
768772
local.exclude.as_deref(),
773+
local.exclude_suffix.as_deref(),
769774
)?;
770775
benchmarks.retain(|b| b.category().is_primary_or_secondary());
771776

@@ -832,6 +837,7 @@ fn main_result() -> anyhow::Result<i32> {
832837
&compile_benchmark_dir,
833838
include.as_deref(),
834839
exclude.as_deref(),
840+
None,
835841
)?;
836842
benchmarks.retain(|b| b.category().is_primary_or_secondary());
837843

@@ -892,6 +898,7 @@ fn main_result() -> anyhow::Result<i32> {
892898
&compile_benchmark_dir,
893899
local.include.as_deref(),
894900
local.exclude.as_deref(),
901+
local.exclude_suffix.as_deref(),
895902
)?;
896903
benchmarks.retain(|b| b.category().is_primary_or_secondary());
897904

@@ -1051,7 +1058,7 @@ fn bench_published_artifact(
10511058
let cargo = which("cargo")?;
10521059

10531060
// Exclude benchmarks that don't work with a stable compiler.
1054-
let mut benchmarks = get_compile_benchmarks(&benchmark_dir, None, None)?;
1061+
let mut benchmarks = get_compile_benchmarks(&benchmark_dir, None, None, None)?;
10551062
benchmarks.retain(|b| b.category().is_stable());
10561063

10571064
let res = bench(

0 commit comments

Comments
 (0)