stak_profiler/
lib.rs

1//! Profiling for Stak Scheme.
2
3extern crate alloc;
4
5mod collapse;
6mod duration;
7mod error;
8mod flamegraph;
9mod read;
10mod record;
11mod reverse;
12mod stack_profiler;
13mod write;
14
15pub use collapse::collapse_stacks;
16pub use duration::calculate_durations;
17pub use error::Error;
18pub use flamegraph::calculate_flamegraph;
19pub use read::read_records;
20pub use record::{
21    DurationRecord, ProcedureOperation, ProcedureRecord, Record, Stack, StackedRecord,
22};
23pub use reverse::reverse_stacks;
24pub use stack_profiler::StackProfiler;
25pub use write::write_records;
26
27const COLUMN_SEPARATOR: char = '\t';
28const FRAME_SEPARATOR: char = ';';
29
30#[cfg(test)]
31mod tests {
32    use super::*;
33    use indoc::indoc;
34    use pretty_assertions::assert_eq;
35    use std::io::BufReader;
36
37    #[test]
38    fn analyze_call() {
39        let mut buffer = vec![];
40
41        write_records(
42            reverse_stacks(calculate_durations(read_records(BufReader::new(
43                indoc!(
44                    "
45                    call\tfoo;bar;baz\t0
46                    return\tfoo;bar;baz\t42
47                    "
48                )
49                .trim()
50                .as_bytes(),
51            )))),
52            &mut buffer,
53        )
54        .unwrap();
55
56        assert_eq!(String::from_utf8(buffer).unwrap(), "baz;bar;foo\t42\n");
57    }
58
59    #[test]
60    fn analyze_nested_calls() {
61        let mut buffer = vec![];
62
63        write_records(
64            reverse_stacks(calculate_durations(read_records(BufReader::new(
65                indoc!(
66                    "
67                    call\tbaz\t0
68                    call\tbar;baz\t1
69                    call\tfoo;bar;baz\t2
70                    return\tfoo;bar;baz\t42
71                    return\tbar;baz\t84
72                    return\tbaz\t126
73                    "
74                )
75                .trim()
76                .as_bytes(),
77            )))),
78            &mut buffer,
79        )
80        .unwrap();
81
82        assert_eq!(
83            String::from_utf8(buffer).unwrap(),
84            indoc!(
85                "
86                baz;bar;foo\t40
87                baz;bar\t83
88                baz\t126
89                "
90            )
91        );
92    }
93
94    #[test]
95    fn analyze_anonymous_procedure_call() {
96        let mut buffer = vec![];
97
98        write_records(
99            reverse_stacks(calculate_durations(read_records(BufReader::new(
100                indoc!(
101                    "
102                    call\t;;\t0
103                    return\t;;\t42
104                    "
105                )
106                .trim()
107                .as_bytes(),
108            )))),
109            &mut buffer,
110        )
111        .unwrap();
112
113        assert_eq!(String::from_utf8(buffer).unwrap(), ";;\t42\n");
114    }
115}