5 unstable releases
new 0.3.0-rc.1 | Nov 24, 2024 |
---|---|
0.2.2 | Nov 3, 2024 |
0.2.1 | Nov 2, 2024 |
0.2.0 |
|
0.1.0 | Oct 31, 2024 |
#213 in Profiling
401 downloads per month
12KB
158 lines
Slow Function Warning
This crate provides a procedural macro to inject timers into functions and print a warning if it takes longer than expected. It can be particularly useful for debugging performance issues during development.
This is not meant to be a benchmarking tool, but rather a way to detect potential performance issues in your code.
For example my use case was for developing a game in Bevy and I've added this to all my systems to detect if any game system function takes longer than a 1ms.
Usage
Installation
Add the following to your Cargo.toml
:
[dependencies]
slow_function_warning = "0.2.0"
# For wasm targets
[target.'cfg(target_family = "wasm")'.dependencies]
web-time = "1"
Basic Example
#[slow_function_warning(1000ms)] // Warn if the function takes longer than 1000 milliseconds
fn example_function() {
// Function implementation
}
Debug Only Example
#[cfg_attr(debug_assertions, slow_function_warning(1000ms))]
fn example_function() {
// Function implementation
}
Or using the convenience proc macro:
#[debug_slow_function_warning(1000ms)]
fn example_function() {
// Function implementation
}
Release Only Example
#[cfg_attr(not(debug_assertions), slow_function_warning(1000ms))]
fn example_function() {
// Function implementation
}
Or using the convenience proc macro:
#[release_slow_function_warning(1000ms)]
fn example_function() {
// Function implementation
}
Custom Message Example
// Warn if the function takes longer than a second with a custom message
#[debug_slow_function_warning(1s, println!("Function {function} took too long!"))]
fn example_function() {
// Function implementation
}
You can also use the function parameters in your message:
// Warn if the function takes longer than a second with a custom message
#[debug_slow_function_warning(1s, println!("Function {function} took {millis} for {} values!", values.len()))]
fn sort(values: &Vec<u32>) {
// Function implementation
}
Duration Syntax
You can specify the duration using numeric literals followed by a suffix:
ns
for nanosecondsms
for millisecondss
for secondsm
for minutesh
for hoursd
for days
Available Variables
module: String
- The name of the modulefunction: String
- The name of the functionelapsed: Duration
- The elapsed timenanos: u64
- The elapsed time in nanosecondsns: u64
- The elapsed time in nanosecondsmillis: u64
- The elapsed time in millisecondsms: u64
- The elapsed time in millisecondssecs: u64
- The elapsed time in secondss: u64
- The elapsed time in seconds
How it works
This is a procedural macro that takes the content of a function and places it in a closure, executes it and times how long it took.
// Warn if the function takes longer than a second with a custom message
#[debug_slow_function_warning(1s, println!("Function {function} took too long!"))]
fn example_function() {
let x = 10;
}
Becomes:
fn example_function() {
let closure = || {
let x = 10;
};
#[cfg(not(target_family = "wasm"))]
let start = std::time::Instant::now();
#[cfg(target_family = "wasm")]
let start = web_time::Instant::now();
let result = closure();
if start.elapsed().as_nanos() > 1000000 {
let module = "module name";
let function = "example_function";
let elapsed = start.elapsed();
let ns = elapsed.as_nanos();
let nanos = ns;
let ms = elapsed.as_millis();
let millis = ms;
let s = elapsed.as_secs();
let secs = s;
println!("Function {function} took too long!")
}
result
}
Dependencies
~0.2–0.8MB
~18K SLoC