Bug 1850713: remove duplicated setting of early hint preloader id in `ScriptLoader...
[gecko.git] / third_party / rust / profiling / README.md
blob64fe3a31b0c0d543e523eae3d9a0ef1c495383b0
1 # profiling
3 Provides a very thin abstraction over instrumented profiling crates like `puffin`, `optick`, `tracy`, and `superluminal-perf`.
5 Mark up your code like this:
7 ```rust
8 #[profiling::function]
9 fn some_function() {
10     burn_time(5);
12     for i in 0..5 {
13         profiling::scope!("Looped Operation");
14     }
16 ```
18 See below for resulting visualization and more details on the exposed API.
20 **Friendly Warning:** Some profiler backends implicitly listen on network ports immediately when the host app is
21 launched. If this is a concern, please review the enabled profiler(s) documentation for details!
23 ## Puffin
25 * https://github.com/EmbarkStudios/puffin
26 * Cross-platform
27 * Unlike the other backends, `puffin` relies on your app providing an imgui window to draw the UI in-process. The
28 below screenshots have a profiled application open with the puffin imgui window visible.
30 ## Optick
32 * https://github.com/bombomby/optick
33 * The upstream crate only provides binaries for windows. However it could probably be made to work by building
34 optick capture code and linking against it manually. The UI is windows only.
36 [![Optick](screenshots/optick-small.png)](screenshots/optick.jpeg)
38 ## Superluminal
40 * https://superluminal.eu
41 * Windows only
43 [![Superluminal](screenshots/superluminal-small.png)](screenshots/superluminal.jpeg)
45 ## Tracing
47 * https://crates.io/crates/tracing
48 * Cross-platform  
49 * The tracing backend injects tracing `span!()` macros that match the lifetime of the profiling macros.
50 Tracing uses callbacks rather than inlining specific pre-determined code,
51 so it is more flexible than profiling
52 (at the cost of more lines of code and potentially higher overhead).
53 This allows existing and new tracing-compatible handlers to work with profiling.
55 ![Tracing](screenshots/tracing.png)
57 ## Tracy
59 * https://github.com/wolfpld/tracy
60 * Cross-platform (windows, macOS, linux)
62 [![Tracy](screenshots/tracy-small.png)](screenshots/tracy.jpeg)
64 ## Usage
66 Currently, there's just four macros:
67  * `profiling::scope!(name: &str, [tag: &str])`
68      * name: scopes will appear in the profiler under this name
69      * tag: optional extra data
70  * `#[profiling::function]`
71      * procmacro placed on a function to quickly wrap it in a scope using the function name
72  * `profiling::register_thread!([name: &str])`
73      * name: optional, defaults to `std::thread::current().name`, or `.id` if it's unnamed
74  * `profiling::finish_frame!()`
75      * Many profilers have the concept of a "frame" as a unit of work. Use this to indicate where one frame ends and the
76        next one begins.
78 Support for individual profilers can be turned on/off with feature flags. By default, they're all off, resulting in
79 no dependencies or runtime code.
81 ## Who is this for?
82  * Authors of binaries that want to have multiple options for profiling their code, but don't want to duplicate their
83    instrumentation once per each profiler's individual API.
84  * Authors of libraries that would like to instrument their crate for their end-users.
86 This crate is intended to be **TINY**. It won't support every possible usage, just the basics. I'm open to adding
87 more things but I plan to be very selective to maintain a slim size.
89 When enabled, using a macro produces identical code as if you used the wrapped profiling API directly. So it is
90 completely fine to directly use a profiler's API when this abstraction doesn't support something you want to do.
92 ## Alternatives
94 **tracing**: `tracing` is more flexible than `profiling` but is significantly larger and has
95 some potential runtime cost. `profiling` is only useful for instrumented profiling. Instrumentation is inserted directly
96 into your code inline via macros as if you were using the profiler's crate directly. This results in smaller code with
97 no additional overhead.
99 Using profiling crates (i.e. puffin/optick/etc.) directly:
100  * For authors of binaries, you may still need to use APIs on those crates to get started. But when instrumenting your
101    code, `profiling::scope!("Scope Name")` inside a function or `#[profiling::function]` on a function will instrument 
102    it for all the supported profiler-specific crates. You can still use those crates directly if you want to take 
103    advantage of custom APIs they provide to surface additional data.
104  * For authors of upstream libraries, this crate lets you implement simple instrumentation once. Hopefully this will
105    allow the community to benefit from instrumented profiling, even if a significant amount of a codebase is made
106    of upstream crates.
108 ## Using from a Binary
110 It's up to you to initialize the profiling crate of your choice (although some do not need explicit initialization
111 and will immediately work). The examples demonstrate this for all the supported crates, but it's worth looking
112 at the docs for the profiler you're interested in using! `profiling` re-exports the profiler crates if they are
113 enabled, simplifying the modifications you would need to make to your Cargo.toml.
115 Once initialized, you can mix/match the macros provided by your profiler of choice and the generic ones in this 
116 crate. For example:
118 ```rust
119 // This may map to something like:
120 // - puffin::profile_scope!("Scope Name")
121 // - optick::event!("Scope Name")
122 // - tracing::span!(tracing::Level::INFO, "Scope Name")
123 // - superluminal_perf::begin_event("Scope Name")
124 profiling::scope!("Scope Name");
126 // This may map to something like:
127 // - puffin::profile_scope_data!("Scope Name", "extra data")
128 // - optick::event!("Scope Name"); optick::tag!("tag", "extra data");
129 // - tracing::span!(tracing::Level::INFO, "Scope Name", tag = "extra data")
130 // - superluminal_perf::begin_event_with_data("Scope Name", "extra data", 0)
131 profiling::scope!("Scope Name", "extra data");
134 There is also a proc macro to decorate functions:
136 ```rust
137 #[profiling::function]
138 fn my_function() {
143 Take a look at the code for the helpful macros `register_thread!()` and `finish_frame!()`. 
145 I recommend adding features for each backend you want to use to your binary crate. This allows you to optionally compile
146 in code to setup and configure a backend.
148 ```toml
149 [dependencies]
150 profiling = "1.0"
152 [features]
153 profile-with-puffin = ["profiling/profile-with-puffin"]
154 profile-with-optick = ["profiling/profile-with-optick"]
155 profile-with-superluminal = ["profiling/profile-with-superluminal"]
156 profile-with-tracing = ["profiling/profile-with-tracing"]
157 profile-with-tracy = ["profiling/profile-with-tracy"]
160  * You can use the default feature to quickly/temporarily turn something on: `default = ["profile-with-optick"]`
161  * `cargo run --features=profile-with-optick` works too!
163 ## Using from a Library
165 Add the profiling crate to Cargo.toml:
167 ```toml
168 [dependencies]
169 profiling = "1.0"
172 Now you can instrument your library using the API exposed via the `profiling` crate.
174 If the end-user of your library doesn't use profiling, the macros in this crate will emit no code at all.
176 ## Feature Flags
178  * profile-with-puffin: Enable the `puffin` crate
179  * profile-with-optick: Enable the `optick` crate
180  * profile-with-superluminal: Enable the `superluminal-perf` crate
181  * profile-with-tracing: Enable the `tracing` crate. (This is just an abstraction layer - you'd want to hook it to do something!)
182  * profile-with-tracy: Enable the `tracy-client` crate.
184 **Only one backend can be enabled at a time!**
186 ## Examples
188  * simple: Shows a bare minimum requirements to do some simple instrumented profiling. Once it's running, you
189    can connect to the process using optick/tracy/superluminal. Some of these are windows only!
192 run --example simple --features="profile-with-optick" 
193 run --example simple --features="profile-with-tracy" 
194 run --example simple --features="profile-with-puffin" 
195 run --example simple --features="profile-with-superluminal" 
198  * puffin: Launches a basic app with imgui integration showing the puffin UI. This one should run everywhere
199    that supports imgui.
202 cargo run --example puffin --features="profile-with-puffin"
205 ## License
207 Licensed under either of
209 * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
210 * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
212 at your option.
214 The examples directory contains [`NotoSans-Medium.ttf`](https://www.google.com/get/noto/), available under SIL Open Font
215 License (OFL).
217 ### Contribution
219 Unless you explicitly state otherwise, any contribution intentionally
220 submitted for inclusion in the work by you, as defined in the Apache-2.0
221 license, shall be dual licensed as above, without any additional terms or
222 conditions.
224 See [LICENSE-APACHE](LICENSE-APACHE) and [LICENSE-MIT](LICENSE-MIT).