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;
}

功能特点

  1. 支持同步和异步函数
  2. 可以自定义日志级别和消息格式
  3. 自动测量并记录函数执行时间
  4. 基于过程宏实现,使用简单

注意事项

  1. 需要在项目中同时使用 logging_timerlogging_timer_proc_macros 两个 crate
  2. 需要初始化日志系统(如 env_logger)才能看到输出
  3. 对于异步函数,需要确保使用兼容的运行时(如 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;
}

示例代码说明

  1. sync_function: 展示了最基本的同步函数用法
  2. custom_log_function: 展示了如何自定义日志级别(warn)和消息格式
  3. async_function: 展示了异步函数的用法
  4. 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();
    }
}

最佳实践

  1. 在开发环境中广泛使用性能分析,生产环境中选择性使用
  2. 为计时器使用有意义的描述信息
  3. 避免在高频调用的函数中使用(除非必要)
  4. 结合log crate的过滤功能控制输出

注意事项

  1. 需要配合log crate使用(如env_logger、simple_logger等)
  2. 会引入少量性能开销(主要是日志记录部分)
  3. 不适合测量极短时间(纳秒级)的操作

这个工具特别适合在开发阶段识别性能瓶颈,或者在复杂系统中监控关键路径的执行时间。

完整示例代码

下面是一个综合使用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
回到顶部