1 use {
2 crate::*,
3 };
4
5 /// Generates a benchmark with a consistent id
6 /// (using the benchmark file title), calling
7 /// the benchmarking functions given in argument.
8 ///
9 /// ```no-test
10 /// glassbench!(
11 /// "Sortings",
12 /// bench_number_sorting,
13 /// bench_alpha_sorting,
14 /// );
15 /// ```
16 ///
17 /// This generates the whole main function.
18 /// If you want to set the bench name yourself
19 /// (not recommanded), or change the way the launch
20 /// arguments are used, you can write the main
21 /// yourself and call [create_bench] and [after_bench]
22 /// instead of using this macro.
23 #[macro_export]
24 macro_rules! glassbench {
25 (
26 $title: literal,
27 $( $fun: path, )+
28 ) => {
29 pub fn main() {
30 use glassbench::*;
31 let name = env!("CARGO_CRATE_NAME");
32 let cmd = Command::read();
33 if cmd.include_bench(&name) {
34 let mut bench = create_bench(name, $title, &cmd);
35 $(
36 $fun(&mut bench);
37 )+
38 if let Err(e) = after_bench(&mut bench, &cmd) {
39 eprintln!("{}", e);
40 }
41 } else {
42 println!("skipping bench {:?}", &name);
43 }
44 }
45 }
46 }
47
48 /// Create a bench with a user defined name (instead of
49 /// the file name) and command (instead of the one read in
50 /// arguments)
51 ///
52 /// Unless you have special reasons, you should not
53 /// use this function but the [glassbench!] function.
create_bench<S1, S2>( name: S1, title: S2, cmd: &Command, ) -> Bench where S1: Into<String>, S2: Into<String>,54 pub fn create_bench<S1, S2>(
55 name: S1,
56 title: S2,
57 cmd: &Command,
58 ) -> Bench
59 where
60 S1: Into<String>,
61 S2: Into<String>,
62 {
63 let mut bench = Bench::new(name, title);
64 bench.tag = cmd.tag.clone();
65 bench
66 }
67
68 /// Print the tabular report for the executed benchmark
69 /// then graph, list history, and or save according to
70 /// command
71 ///
72 /// Unless you have special reasons, you should not
73 /// use this function but the [glassbench!] function.
after_bench( bench: &mut Bench, cmd: &Command, ) -> Result<(), GlassBenchError>74 pub fn after_bench(
75 bench: &mut Bench,
76 cmd: &Command,
77 ) -> Result<(), GlassBenchError> {
78 let printer = Printer::new();
79 let mut db = Db::open()?;
80 let previous = db.last_bench_named(&bench.name)?;
81 let report = Report::new(&bench, &previous);
82 report.print(&printer);
83 let mut no_save = cmd.no_save;
84 if let Some(graph_arg) = cmd.graph.as_ref() {
85 let task_name = bench.task_name_from_arg(graph_arg);
86 let viewer = HtmlViewer::new(&bench.name, task_name);
87 viewer.open_in_browser()?;
88 no_save = true;
89 }
90 if let Some(tbl_arg) = cmd.history.as_ref() {
91 let history = bench.task_history(&mut db, tbl_arg)?;
92 let tbl = HistoryTbl::new(&history);
93 tbl.print(&printer);
94 no_save = true;
95 }
96 if !no_save {
97 db.save_bench(&bench)?;
98 }
99 Ok(())
100 }
101