refactor benchmarks code

This commit is contained in:
Mazdak Farrokhzad 2022-07-27 19:40:19 +02:00
parent 9dd45c3620
commit 86ae9e1727
2 changed files with 86 additions and 147 deletions

View File

@ -18,10 +18,7 @@
use leo_compiler::Compiler; use leo_compiler::Compiler;
use leo_errors::emitter::{Emitter, Handler}; use leo_errors::emitter::{Emitter, Handler};
use leo_span::{ use leo_span::{source_map::FileName, symbol::SESSION_GLOBALS};
source_map::FileName,
symbol::{SessionGlobals, SESSION_GLOBALS},
};
use leo_test_framework::get_benches; use leo_test_framework::get_benches;
use criterion::{black_box, criterion_group, criterion_main, Criterion}; use criterion::{black_box, criterion_group, criterion_main, Criterion};
@ -110,122 +107,79 @@ impl Sample {
} }
} }
fn bench_parse(&self, c: &mut Criterion) { /// Benchmarks `logic(compiler)` where `compiler` is provided.
c.bench_function(&format!("parse {}", self.name), |b| { fn bencher(&self, c: &mut Criterion, mode: &str, mut logic: impl FnMut(Compiler) -> Duration) {
c.bench_function(&format!("{} {}", mode, self.name), |b| {
// Iter custom is used so we can use custom timings around the compiler stages. // Iter custom is used so we can use custom timings around the compiler stages.
// This way we can only time the necessary stage. // This way we can only time the necessary stage.
b.iter_custom(|iters| { b.iter_custom(|iters| {
let mut time = Duration::default(); (0..iters)
for _ in 0..iters { .map(|_| SESSION_GLOBALS.set(&<_>::default(), || logic(new_compiler(&BufEmitter::new_handler()))))
SESSION_GLOBALS.set(&SessionGlobals::default(), || { .sum()
let handler = BufEmitter::new_handler();
let mut compiler = new_compiler(&handler);
let (input, name) = self.data();
let start = Instant::now();
let out = compiler.parse_program_from_string(input, name);
time += start.elapsed();
out.expect("Failed to parse program")
}); });
}
time
})
}); });
} }
fn bench_symbol_table(&self, c: &mut Criterion) { /// Benchmarks `logic(compiler)` where `compiler` is provided.
c.bench_function(&format!("symbol table pass {}", self.name), |b| { /// Parsing has already been done.
// Iter custom is used so we can use custom timings around the compiler stages. fn bencher_after_parse(&self, c: &mut Criterion, mode: &str, mut logic: impl FnMut(Compiler) -> Duration) {
// This way we can only time the necessary stage. self.bencher(c, mode, |mut compiler| {
b.iter_custom(|iters| {
let mut time = Duration::default();
for _ in 0..iters {
SESSION_GLOBALS.set(&SessionGlobals::default(), || {
let handler = BufEmitter::new_handler();
let mut compiler = new_compiler(&handler);
let (input, name) = self.data(); let (input, name) = self.data();
compiler compiler
.parse_program_from_string(input, name) .parse_program_from_string(input, name)
.expect("Failed to parse program"); .expect("Failed to parse program");
let start = Instant::now(); logic(compiler)
let out = compiler.symbol_table_pass();
time += start.elapsed();
out.expect("failed to generate symbol table");
}); });
} }
fn bench_parse(&self, c: &mut Criterion) {
self.bencher(c, "parse", |mut compiler| {
let (input, name) = self.data();
let start = Instant::now();
let out = compiler.parse_program_from_string(input, name);
let time = start.elapsed();
out.expect("Failed to parse program");
time time
}) })
}
fn bench_symbol_table(&self, c: &mut Criterion) {
self.bencher_after_parse(c, "symbol table pass", |compiler| {
let start = Instant::now();
let out = compiler.symbol_table_pass();
let time = start.elapsed();
out.expect("failed to generate symbol table");
time
}); });
} }
fn bench_type_checker(&self, c: &mut Criterion) { fn bench_type_checker(&self, c: &mut Criterion) {
c.bench_function(&format!("type checker pass {}", self.name), |b| { self.bencher_after_parse(c, "type checker pass", |compiler| {
// Iter custom is used so we can use custom timings around the compiler stages.
// This way we can only time the necessary stage.
b.iter_custom(|iters| {
let mut time = Duration::default();
for _ in 0..iters {
SESSION_GLOBALS.set(&SessionGlobals::default(), || {
let handler = BufEmitter::new_handler();
let mut compiler = new_compiler(&handler);
let (input, name) = self.data();
compiler
.parse_program_from_string(input, name)
.expect("Failed to parse program");
let symbol_table = compiler.symbol_table_pass().expect("failed to generate symbol table"); let symbol_table = compiler.symbol_table_pass().expect("failed to generate symbol table");
let start = Instant::now(); let start = Instant::now();
let out = compiler.type_checker_pass(symbol_table); let out = compiler.type_checker_pass(symbol_table);
time += start.elapsed(); let time = start.elapsed();
out.expect("failed to run type check pass") out.expect("failed to run type check pass");
});
}
time time
})
}); });
} }
fn bench_loop_unroller(&self, c: &mut Criterion) { fn bench_loop_unroller(&self, c: &mut Criterion) {
c.bench_function(&format!("loop unrolling pass{}", self.name), |b| { self.bencher_after_parse(c, "loop unrolling pass", |mut compiler| {
// Iter custom is used so we can use custom timings around the compiler stages.
// This way we can only time the necessary stage.
b.iter_custom(|iters| {
let mut time = Duration::default();
for _ in 0..iters {
SESSION_GLOBALS.set(&SessionGlobals::default(), || {
let handler = BufEmitter::new_handler();
let mut compiler = new_compiler(&handler);
let (input, name) = self.data();
compiler
.parse_program_from_string(input, name)
.expect("Failed to parse program");
let symbol_table = compiler.symbol_table_pass().expect("failed to generate symbol table"); let symbol_table = compiler.symbol_table_pass().expect("failed to generate symbol table");
let symbol_table = compiler let symbol_table = compiler
.type_checker_pass(symbol_table) .type_checker_pass(symbol_table)
.expect("failed to run type check pass"); .expect("failed to run type check pass");
let start = Instant::now(); let start = Instant::now();
let out = compiler.loop_unrolling_pass(symbol_table); let out = compiler.loop_unrolling_pass(symbol_table);
time += start.elapsed(); let time = start.elapsed();
out.expect("failed to run loop unrolling pass") out.expect("failed to run loop unrolling pass");
});
}
time time
})
}); });
} }
fn bench_ssa(&self, c: &mut Criterion) { fn bench_ssa(&self, c: &mut Criterion) {
c.bench_function(&format!("full {}", self.name), |b| { self.bencher_after_parse(c, "full", |mut compiler| {
// Iter custom is used so we can use custom timings around the compiler stages.
// This way we can only time the necessary stages.
b.iter_custom(|iters| {
let mut time = Duration::default();
for _ in 0..iters {
SESSION_GLOBALS.set(&SessionGlobals::default(), || {
let handler = BufEmitter::new_handler();
let mut compiler = new_compiler(&handler);
let (input, name) = self.data();
compiler
.parse_program_from_string(input, name)
.expect("Failed to parse program");
let symbol_table = compiler.symbol_table_pass().expect("failed to generate symbol table"); let symbol_table = compiler.symbol_table_pass().expect("failed to generate symbol table");
let symbol_table = compiler let symbol_table = compiler
.type_checker_pass(symbol_table) .type_checker_pass(symbol_table)
@ -235,25 +189,14 @@ impl Sample {
.expect("failed to run loop unrolling pass"); .expect("failed to run loop unrolling pass");
let start = Instant::now(); let start = Instant::now();
let out = compiler.static_single_assignment_pass(); let out = compiler.static_single_assignment_pass();
time += start.elapsed(); let time = start.elapsed();
out.expect("failed to run ssa pass") out.expect("failed to run ssa pass");
});
}
time time
}) })
});
} }
fn bench_full(&self, c: &mut Criterion) { fn bench_full(&self, c: &mut Criterion) {
c.bench_function(&format!("full {}", self.name), |b| { self.bencher(c, "full", |mut compiler| {
// Iter custom is used so we can use custom timings around the compiler stages.
// This way we can only time the necessary stages.
b.iter_custom(|iters| {
let mut time = Duration::default();
for _ in 0..iters {
SESSION_GLOBALS.set(&SessionGlobals::default(), || {
let handler = BufEmitter::new_handler();
let mut compiler = new_compiler(&handler);
let (input, name) = self.data(); let (input, name) = self.data();
let start = Instant::now(); let start = Instant::now();
compiler compiler
@ -269,12 +212,8 @@ impl Sample {
compiler compiler
.static_single_assignment_pass() .static_single_assignment_pass()
.expect("failed to run ssa pass"); .expect("failed to run ssa pass");
time += start.elapsed(); start.elapsed()
});
}
time
}) })
});
} }
} }