Skip to main content

timetrace/
lib.rs

1#[cfg(feature = "macros")]
2pub use timetrace_macros::{profile_function, profile_session, profile_session_limited};
3
4mod backends;
5pub mod profile_result;
6pub mod profiler;
7pub mod profiler_timer;
8pub use profiler_timer::ProfilerTimer;
9
10pub use backends::base::TracingBackend;
11
12#[cfg(all(feature = "tracy", feature = "json"))]
13compile_error!("features 'tracy' and 'json' are mutually exclusive");
14
15/**
16# Timetrace
17
18A lightweight Rust profiling library inspired by Hazel and Tracy-style instrumentation.
19
20Generates JSON traces compatible with Chrome Tracing and Perfetto.
21and supports tracy.
22
23
24## Features
25
26- RAII profiling (scope-based)
27- Function attribute macro: `#[profile_function]`
28- Session management: `#[profile_session]`
29- Frame indexing in trace (`args.frame`)
30- Minimal overhead
31- Thread-aware (thread id included)
32
33
34## Example
35
36```rust
37use timetrace::{profile_function, profile_session};
38
39#[profile_session("Example", "trace.json")]
40fn main() {
41    work();
42}
43
44#[profile_function]
45fn work() {
46    let mut sum = 0.0;
47
48    for i in 0..1_000_000 {
49        sum += (i as f64).cos();
50    }
51
52    println!("{sum}");
53}
54```
55
56
57## Run
58
59```bash
60cargo run -p timetrace_example
61```
62
63
64## View Trace
65
66Open in:
67
68- https://ui.perfetto.dev
69- Only in Google Chrome: chrome://tracing
70
71
72## Output Example
73```json
74{
75  "name": "work",
76  "cat": "function",
77  "ph": "X",
78  "ts": 123456789,
79  "dur": 23000,
80  "pid": 0,
81  "tid": 12345,
82  "args": {
83    "frame": 0
84  }
85}
86```
87(Actual output is written as a single line JSON)
88
89
90## Cargo Features
91
92Enable macros:
93
94```toml
95timetrace = { path = "...", features = ["json"] }
96```
97(macros are enabled by default)
98
99Disable macros:
100```toml
101timetrace = { path = "...", features = ["json"], default-features = false }
102```
103*/
104
105#[macro_export]
106macro_rules! profile_begin_session {
107    ($name:expr, $filepath:expr) => {
108        use $crate::TracingBackend;
109        $crate::profiler::Profiler::get()
110            .lock()
111            .begin_session($name, $filepath);
112    };
113}
114
115#[macro_export]
116macro_rules! profile_begin_session_limited {
117    ($name:expr, $path:expr, $frames:expr, $ms:expr) => {
118        use $crate::TracingBackend;
119        $crate::profiler::Profiler::get()
120            .lock()
121            .begin_session_limited($name, $path, $frames, $ms);
122    };
123}
124
125#[macro_export]
126macro_rules! profile_end_session {
127    () => {
128        use $crate::TracingBackend;
129        $crate::profiler::Profiler::get()
130            .lock()
131            .end_session()
132            .unwrap();
133    };
134}
135
136#[macro_export]
137macro_rules! profile_scope {
138    ($name:expr) => {
139        use $crate::TracingBackend;
140        let _timer = $crate::profiler_timer::ProfilerTimer::new($name);
141    };
142}
143
144#[macro_export]
145macro_rules! profile_function_scope {
146    () => {
147        use $crate::TracingBackend;
148        let _timer = $crate::profiler_timer::ProfilerTimer::new(module_path!());
149    };
150}
151
152#[macro_export]
153macro_rules! profile_new_frame {
154    () => {
155        use $crate::TracingBackend;
156        $crate::profiler::Profiler::get().lock().new_frame();
157    };
158}
159#[macro_export]
160macro_rules! profile_update {
161    ($name:expr, $value:expr) => {
162        use $crate::TracingBackend;
163        profile_new_frame!();
164    };
165}