Merge nucleic/sleek-thistle-egret-fyej into dev
This commit is contained in:
@@ -0,0 +1,174 @@
|
||||
//! Benchmarks for the brush-shell crate.
|
||||
|
||||
#![allow(missing_docs)]
|
||||
#![allow(clippy::unwrap_used)]
|
||||
|
||||
#[cfg(unix)]
|
||||
mod unix {
|
||||
use brush_builtins::ShellBuilderExt;
|
||||
use brush_parser::SourceSpan;
|
||||
use criterion::Criterion;
|
||||
use std::hint::black_box;
|
||||
|
||||
async fn instantiate_shell() -> brush_core::Shell {
|
||||
brush_core::Shell::builder()
|
||||
.default_builtins(brush_builtins::BuiltinSet::BashMode)
|
||||
.build()
|
||||
.await
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
async fn instantiate_shell_with_init_scripts() -> brush_core::Shell {
|
||||
brush_core::Shell::builder()
|
||||
.interactive(true)
|
||||
.read_commands_from_stdin(true)
|
||||
.default_builtins(brush_builtins::BuiltinSet::BashMode)
|
||||
.build()
|
||||
.await
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
async fn run_one_command(shell: &mut brush_core::Shell, command: &str) {
|
||||
let _ = shell
|
||||
.run_string(
|
||||
command.to_owned(),
|
||||
&brush_core::SourceInfo::default(),
|
||||
&shell.default_exec_params(),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
async fn expand_string(shell: &mut brush_core::Shell, s: &str) {
|
||||
let params = shell.default_exec_params();
|
||||
let _ = shell.basic_expand_string(¶ms, s).await.unwrap();
|
||||
}
|
||||
|
||||
fn eval_arithmetic_expr(shell: &mut brush_core::Shell, expr: &str) {
|
||||
let parsed_expr = brush_parser::arithmetic::parse(expr).unwrap();
|
||||
let _ = shell.eval_arithmetic(&parsed_expr).unwrap();
|
||||
}
|
||||
|
||||
/// This function defines core shell benchmarks.
|
||||
pub(crate) fn criterion_benchmark(c: &mut Criterion) {
|
||||
// Construct a runtime for us to run async code on.
|
||||
let rt = tokio::runtime::Builder::new_multi_thread()
|
||||
.enable_all()
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
// Benchmark shell instantiation.
|
||||
c.bench_function("instantiate_shell", |b| {
|
||||
b.to_async(&rt).iter(|| black_box(instantiate_shell()));
|
||||
});
|
||||
c.bench_function("instantiate_shell_with_init_scripts", |b| {
|
||||
b.to_async(&rt)
|
||||
.iter(|| black_box(instantiate_shell_with_init_scripts()));
|
||||
});
|
||||
|
||||
// Benchmark: cloning a shell object.
|
||||
let shell = rt.block_on(instantiate_shell());
|
||||
c.bench_function("clone_shell_object", |b| {
|
||||
b.iter(|| black_box(shell.clone()));
|
||||
});
|
||||
|
||||
// Benchmark: parsing and evaluating an arithmetic expression..
|
||||
let shell = rt.block_on(instantiate_shell());
|
||||
c.bench_function("eval_arithmetic", |b| {
|
||||
b.iter_batched_ref(
|
||||
|| shell.clone(),
|
||||
|s| eval_arithmetic_expr(s, "3 + 10 * 2"),
|
||||
criterion::BatchSize::SmallInput,
|
||||
);
|
||||
});
|
||||
|
||||
// Benchmark: running the echo built-in command.
|
||||
let shell = rt.block_on(instantiate_shell());
|
||||
c.bench_function("run_echo_builtin_command", |b| {
|
||||
b.iter_batched_ref(
|
||||
|| shell.clone(),
|
||||
|s| rt.block_on(run_one_command(s, "echo 'Hello, world!' >/dev/null")),
|
||||
criterion::BatchSize::SmallInput,
|
||||
);
|
||||
});
|
||||
|
||||
// Benchmark: running an external command.
|
||||
// let shell = rt.block_on(instantiate_shell());
|
||||
// c.bench_function("run_one_external_command", |b| {
|
||||
// b.iter_batched_ref(
|
||||
// || shell.clone(),
|
||||
// |s| {
|
||||
// rt.block_on(run_one_command(
|
||||
// s,
|
||||
// "/usr/bin/echo 'Hello, world!' >/dev/null",
|
||||
// ));
|
||||
// },
|
||||
// criterion::BatchSize::SmallInput,
|
||||
// );
|
||||
// });
|
||||
|
||||
// Benchmark: word expansion.
|
||||
let shell = rt.block_on(instantiate_shell());
|
||||
c.bench_function("expand_one_string", |b| {
|
||||
b.iter_batched_ref(
|
||||
|| shell.clone(),
|
||||
|s| rt.block_on(expand_string(s, "My version is ${BASH_VERSINFO[@]}")),
|
||||
criterion::BatchSize::SmallInput,
|
||||
);
|
||||
});
|
||||
|
||||
// Benchmark: function invocation.
|
||||
let mut shell = rt.block_on(instantiate_shell());
|
||||
shell.define_func(
|
||||
String::from("testfunc"),
|
||||
brush_parser::ast::FunctionDefinition {
|
||||
fname: String::from("testfunc").into(),
|
||||
body: brush_parser::ast::FunctionBody(
|
||||
brush_parser::ast::CompoundCommand::BraceGroup(
|
||||
brush_parser::ast::BraceGroupCommand {
|
||||
list: brush_parser::ast::CompoundList(vec![]),
|
||||
loc: SourceSpan::default(),
|
||||
},
|
||||
),
|
||||
None,
|
||||
),
|
||||
},
|
||||
&brush_core::SourceInfo::default(),
|
||||
);
|
||||
c.bench_function("function_call", |b| {
|
||||
b.iter_batched_ref(
|
||||
|| shell.clone(),
|
||||
|s| {
|
||||
rt.block_on(run_one_command(s, "testfunc"));
|
||||
},
|
||||
criterion::BatchSize::SmallInput,
|
||||
);
|
||||
});
|
||||
|
||||
// Benchmark: for loop.
|
||||
let shell = rt.block_on(instantiate_shell());
|
||||
c.bench_function("for_loop", |b| {
|
||||
b.iter_batched_ref(
|
||||
|| shell.clone(),
|
||||
|s| {
|
||||
rt.block_on(run_one_command(s, "for ((i = 0; i < 10; i++)); do :; done"));
|
||||
},
|
||||
criterion::BatchSize::SmallInput,
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
criterion::criterion_group! {
|
||||
name = benches;
|
||||
config = criterion::Criterion::default()
|
||||
.measurement_time(std::time::Duration::from_secs(10));
|
||||
targets = unix::criterion_benchmark
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
criterion::criterion_main!(benches);
|
||||
|
||||
#[cfg(not(unix))]
|
||||
fn main() {}
|
||||
Reference in New Issue
Block a user