1 use std::fs::File;
2 use std::io::{self, Read};
3 
4 use criterion::*;
5 use inferno::collapse::{dtrace, perf, sample, Collapse};
6 use lazy_static::lazy_static;
7 use libflate::gzip::Decoder;
8 
9 const INFILE_DTRACE: &str = "flamegraph/example-dtrace-stacks.txt";
10 const INFILE_PERF: &str = "flamegraph/example-perf-stacks.txt.gz";
11 const INFILE_SAMPLE: &str = "tests/data/collapse-sample/large.txt.gz";
12 const SAMPLE_SIZE: usize = 100;
13 
14 lazy_static! {
15     static ref NTHREADS: usize = num_cpus::get();
16 }
17 
read_infile(infile: &str, buf: &mut Vec<u8>) -> io::Result<()>18 fn read_infile(infile: &str, buf: &mut Vec<u8>) -> io::Result<()> {
19     let mut f = File::open(infile)?;
20     if infile.ends_with(".gz") {
21         let mut r = io::BufReader::new(Decoder::new(f)?);
22         r.read_to_end(buf)?;
23     } else {
24         f.read_to_end(buf)?;
25     }
26     Ok(())
27 }
28 
29 macro_rules! benchmark_single {
30     ($name:ident, $name_str:expr, $infile:expr) => {
31         fn $name(c: &mut Criterion) {
32             let mut bytes = Vec::new();
33             read_infile($infile, &mut bytes).unwrap();
34 
35             let mut collapser = $name::Folder::default();
36 
37             c.bench(
38                 "collapse",
39                 ParameterizedBenchmark::new(
40                     $name_str,
41                     move |b, data| {
42                         b.iter(|| {
43                             let _result = collapser.collapse(data.as_slice(), io::sink());
44                         })
45                     },
46                     vec![bytes],
47                 )
48                 .throughput(|bytes| Throughput::Bytes(bytes.len() as u64))
49                 .sample_size(SAMPLE_SIZE),
50             );
51         }
52     };
53 }
54 
55 macro_rules! benchmark_multi {
56     ($name:ident, $name_str:expr, $infile:expr) => {
57         fn $name(c: &mut Criterion) {
58             let mut bytes = Vec::new();
59             read_infile($infile, &mut bytes).unwrap();
60 
61             let mut collapser1 = {
62                 let mut options = $name::Options::default();
63                 options.nthreads = 1;
64                 $name::Folder::from(options)
65             };
66 
67             let mut collapser2 = {
68                 let mut options = $name::Options::default();
69                 options.nthreads = *NTHREADS;
70                 $name::Folder::from(options)
71             };
72 
73             c.bench(
74                 "collapse",
75                 ParameterizedBenchmark::new(
76                     format!("{}/1", $name_str),
77                     move |b, data| {
78                         b.iter(|| {
79                             let _result = collapser1.collapse(data.as_slice(), io::sink());
80                         })
81                     },
82                     vec![bytes],
83                 )
84                 .with_function(format!("{}/{}", $name_str, *NTHREADS), move |b, data| {
85                     b.iter(|| {
86                         let _result = collapser2.collapse(data.as_slice(), io::sink());
87                     })
88                 })
89                 .throughput(|bytes| Throughput::Bytes(bytes.len() as u64))
90                 .sample_size(SAMPLE_SIZE),
91             );
92         }
93     };
94 }
95 
96 benchmark_multi!(dtrace, "dtrace", INFILE_DTRACE);
97 benchmark_multi!(perf, "perf", INFILE_PERF);
98 benchmark_single!(sample, "sample", INFILE_SAMPLE);
99 
100 criterion_group!(benches, dtrace, perf, sample);
101 
102 criterion_main!(benches);
103