Rust性能分析插件logging_timer_proc_macros的使用:基于过程宏的代码执行时间测量与日志记录工具
Rust性能分析插件logging_timer_proc_macros的使用:基于过程宏的代码执行时间测量与日志记录工具
概述
logging_timer_proc_macros
是一个 Rust 的过程宏实现,用于为 logging_timer
库提供宏支持。该工具主要用于测量代码执行时间并记录日志。
安装
在您的项目目录中运行以下 Cargo 命令:
cargo add logging_timer_proc_macros
或者将以下行添加到您的 Cargo.toml
文件中:
logging_timer_proc_macros = "1.1.1"
示例代码
以下是一个使用 logging_timer_proc_macros
的完整示例:
use logging_timer_proc_macros::time;
// 使用 #[time] 宏来测量函数执行时间
#[time]
fn expensive_operation() {
// 模拟耗时操作
std::thread::sleep(std::time::Duration::from_millis(100));
println!("Operation completed");
}
// 可以自定义日志级别和消息
#[time("info", "Custom message - {}")]
fn operation_with_custom_message(name: &str) -> u32 {
std::thread::sleep(std::time::Duration::from_millis(50));
println!("Operation {} completed", name);
42
}
// 异步函数也可以使用
#[time]
async fn async_operation() {
tokio::time::sleep(std::time::Duration::from_millis(75)).await;
println!("Async operation completed");
}
#[tokio::main]
async fn main() {
// 初始化日志系统
env_logger::init();
expensive_operation();
let result = operation_with_custom_message("test");
println!("Result: {}", result);
async_operation().await;
}
功能特点
- 支持同步和异步函数
- 可以自定义日志级别和消息格式
- 自动测量并记录函数执行时间
- 基于过程宏实现,使用简单
注意事项
- 需要在项目中同时使用
logging_timer
和logging_timer_proc_macros
两个 crate - 需要初始化日志系统(如
env_logger
)才能看到输出 - 对于异步函数,需要确保使用兼容的运行时(如
tokio
)
许可证
该项目使用 MIT 许可证。
完整示例代码
以下是一个更完整的示例,展示了不同场景下的用法:
use logging_timer_proc_macros::time;
use log::{info, LevelFilter};
use std::thread;
use std::time::Duration;
// 1. 基本用法 - 同步函数
#[time] // 默认使用info级别日志
fn sync_function() {
thread::sleep(Duration::from_millis(100));
info!("同步函数执行完成");
}
// 2. 自定义日志级别和消息 - 同步函数
#[time("warn", "耗时操作 - 参数: {}")]
fn custom_log_function(param: &str) -> usize {
thread::sleep(Duration::from_millis(150));
param.len()
}
// 3. 异步函数支持
#[time]
async fn async_function() {
tokio::time::sleep(Duration::from_millis(80)).await;
info!("异步函数执行完成");
}
// 4. 返回值的函数
#[time]
fn function_with_return() -> i32 {
thread::sleep(Duration::from_millis(50));
42
}
#[tokio::main]
async fn main() {
// 初始化日志系统
env_logger::builder()
.filter_level(LevelFilter::Info)
.init();
// 测试各种函数
sync_function();
let len = custom_log_function("测试参数");
info!("返回值: {}", len);
let result = function_with_return();
info!("返回值: {}", result);
async_function().await;
}
示例代码说明
sync_function
: 展示了最基本的同步函数用法custom_log_function
: 展示了如何自定义日志级别(warn)和消息格式async_function
: 展示了异步函数的用法function_with_return
: 展示了带返回值函数的用法
要运行此示例,请确保在Cargo.toml中添加了所有必要的依赖项:
[dependencies]
logging_timer_proc_macros = "1.1.1"
logging_timer = "1.1.1"
env_logger = "0.10"
tokio = { version = "1.0", features = ["full"] }
log = "0.4"
运行程序后,您将在控制台看到类似以下输出:
[INFO] sync_function: 开始
同步函数执行完成
[INFO] sync_function: 结束 - 耗时: 100.23ms
[WARN] 耗时操作 - 参数: 测试参数: 开始
[WARN] 耗时操作 - 参数: 测试参数: 结束 - 耗时: 150.15ms
[INFO] 返回值: 12
[INFO] function_with_return: 开始
[INFO] function_with_return: 结束 - 耗时: 50.12ms
[INFO] 返回值: 42
[INFO] async_function: 开始
异步函数执行完成
[INFO] async_function: 结束 - 耗时: 80.08ms
1 回复
Rust性能分析插件logging_timer_proc_macros使用指南
logging_timer_proc_macros
是一个基于过程宏的Rust性能分析工具,它可以方便地测量代码块的执行时间并将结果记录到日志中。
安装
在Cargo.toml
中添加依赖:
[dependencies]
logging_timer_proc_macros = "1.0"
log = "0.4" # 需要配合log crate使用
基本用法
1. 测量函数执行时间
使用#[time("message")]
属性宏来测量整个函数的执行时间:
use logging_timer_proc_macros::time;
use log::info;
#[time("Function execution")]
fn my_function() {
// 这里是一些耗时操作
std::thread::sleep(std::time::Duration::from_millis(100));
}
fn main() {
env_logger::init();
my_function();
}
输出示例:
INFO [logging_timer] Starting 'Function execution'
INFO [logging_timer] Finished 'Function execution' in 100.23ms
2. 测量代码块执行时间
使用time!
宏来测量特定代码块的执行时间:
use logging_timer_proc_macros::time;
use log::info;
fn main() {
env_logger::init();
time!("Block execution", {
// 这里是一些耗时操作
std::thread::sleep(std::time::Duration::from_millis(50));
});
// 也可以这样写
let result = time!("Block with return value", {
std::thread::sleep(std::time::Duration::from_millis(20));
42
});
info!("Result: {}", result);
}
3. 嵌套计时
宏支持嵌套使用,可以测量复杂代码结构中的各个部分:
#[time("Outer function")]
fn outer_function() {
std::thread::sleep(std::time::Duration::from_millis(50));
#[time("Inner function")]
fn inner_function() {
std::thread::sleep(std::time::Duration::from_millis(20));
}
inner_function();
}
高级用法
1. 自定义日志级别
默认使用info!
级别,可以指定其他日志级别:
#[time("Function execution", level = "debug")]
fn my_function() {
// ...
}
time!("Block execution", level = "warn", {
// ...
});
2. 条件性计时
只在特定条件下启用计时:
#[time("Function execution", enabled = cfg!(debug_assertions))]
fn debug_only_function() {
// 这段代码只在debug模式下计时
}
3. 多线程支持
宏会自动处理多线程环境,每个线程会有独立的计时:
use std::thread;
#[time("Thread work")]
fn do_work() {
std::thread::sleep(std::time::Duration::from_millis(100));
}
fn main() {
env_logger::init();
let handles: Vec<_> = (0..3).map(|_| {
thread::spawn(|| {
do_work();
})
}).collect();
for handle in handles {
handle.join().unwrap();
}
}
最佳实践
- 在开发环境中广泛使用性能分析,生产环境中选择性使用
- 为计时器使用有意义的描述信息
- 避免在高频调用的函数中使用(除非必要)
- 结合log crate的过滤功能控制输出
注意事项
- 需要配合log crate使用(如env_logger、simple_logger等)
- 会引入少量性能开销(主要是日志记录部分)
- 不适合测量极短时间(纳秒级)的操作
这个工具特别适合在开发阶段识别性能瓶颈,或者在复杂系统中监控关键路径的执行时间。
完整示例代码
下面是一个综合使用logging_timer_proc_macros的完整示例:
use logging_timer_proc_macros::{time, time_};
use log::{info, warn};
// 测量函数执行时间
#[time("Database query")]
fn query_database() -> Vec<String> {
// 模拟数据库查询
std::thread::sleep(std::time::Duration::from_millis(80));
vec!["data1".to_string(), "data2".to_string()]
}
// 条件性计时 - 只在debug模式启用
#[time("Expensive calculation", enabled = cfg!(debug_assertions))]
fn expensive_calculation() -> i32 {
std::thread::sleep(std::time::Duration::from_millis(30));
42
}
fn main() {
// 初始化日志
env_logger::init();
// 示例1: 测量函数执行时间
let data = query_database();
info!("Got {} items", data.len());
// 示例2: 测量代码块执行时间
let result = time!("Complex processing", {
let mut total = 0;
for i in 0..5 {
// 嵌套计时
time!("Inner loop iteration", {
std::thread::sleep(std::time::Duration::from_millis(10));
total += i;
});
}
total
});
info!("Processing result: {}", result);
// 示例3: 自定义日志级别
time_!("Warning level timer", level = "warn", {
std::thread::sleep(std::time::Duration::from_millis(15));
});
// 示例4: 条件性计时函数
let calc_result = expensive_calculation();
warn!("Calculation result: {}", calc_result);
// 示例5: 多线程计时
let handles: Vec<_> = (0..2).map(|i| {
std::thread::spawn(move || {
#[time("Thread worker")]
fn worker_task(id: usize) {
std::thread::sleep(std::time::Duration::from_millis(50 + (id as u64) * 20));
}
worker_task(i);
})
}).collect();
for handle in handles {
handle.join().unwrap();
}
}
输出示例:
INFO [logging_timer] Starting 'Database query'
INFO [logging_timer] Finished 'Database query' in 80.12ms
INFO Got 2 items
INFO [logging_timer] Starting 'Complex processing'
INFO [logging_timer] Starting 'Inner loop iteration'
INFO [logging_timer] Finished 'Inner loop iteration' in 10.05ms
INFO [logging_timer] Starting 'Inner loop iteration'
INFO [logging_timer] Finished 'Inner loop iteration' in 10.03ms
INFO [logging_timer] Starting 'Inner loop iteration'
INFO [logging_timer] Finished 'Inner loop iteration' in 10.02ms
INFO [logging_timer] Starting 'Inner loop iteration'
INFO [logging_timer] Finished 'Inner loop iteration' in 10.04ms
INFO [logging_timer] Starting 'Inner loop iteration'
INFO [logging_timer] Finished 'Inner loop iteration' in 10.01ms
INFO [logging_timer] Finished 'Complex processing' in 50.23ms
INFO Processing result: 10
WARN [logging_timer] Starting 'Warning level timer'
WARN [logging_timer] Finished 'Warning level timer' in 15.08ms
WARN [logging_timer] Starting 'Expensive calculation'
WARN [logging_timer] Finished 'Expensive calculation' in 30.15ms
WARN Calculation result: 42
INFO [logging_timer] Starting 'Thread worker'
INFO [logging_timer] Starting 'Thread worker'
INFO [logging_timer] Finished 'Thread worker' in 50.11ms
INFO [logging_timer] Finished 'Thread worker' in 70.18ms