#proc-macro #profiling #flame-graph #compiler-plugin

flamer

一个用于插入 flame::start_guard(_) 调用的过程宏

12 个版本

使用旧的Rust 2015

0.5.0 2023年4月13日
0.4.0 2019年8月15日
0.3.0 2018年11月6日
0.2.5 2018年7月13日
0.1.2 2016年7月8日

过程宏 中排名第 165

Download history 231/week @ 2024-03-13 244/week @ 2024-03-20 263/week @ 2024-03-27 287/week @ 2024-04-03 256/week @ 2024-04-10 244/week @ 2024-04-17 270/week @ 2024-04-24 334/week @ 2024-05-01 324/week @ 2024-05-08 265/week @ 2024-05-15 306/week @ 2024-05-22 302/week @ 2024-05-29 391/week @ 2024-06-05 388/week @ 2024-06-12 731/week @ 2024-06-19 283/week @ 2024-06-26

每月下载量 1,848
用于 16 crate(14 个直接使用)

Apache-2.0 协议

11KB
129

一个过程宏,用于插入适当的 flame::start_guard(_) 调用(与 flame 一起使用)

Build Status Current Version Docs Supported Rust Versions

此过程宏需要Rust 1.30。 因为flamer是一个过程宏属性,它使用了Rust 1.30中稳定的API。

用法

在 Cargo.toml 中将 flameflamer 添加到依赖项中

[dependencies]
flame = "0.2.2"
flamer = "0.5"

然后在您的crate根目录下,添加以下内容

extern crate flame;
#[macro_use] extern crate flamer;

#[flame]
// The item to apply `flame` to goes here.

遗憾的是,目前稳定的Rust不允许在模块上使用自定义属性。要在模块上使用 #[flame],您需要一个带有 #![feature(proc_macro_hygiene)] 的nightly Rust(相关问题

#![feature(proc_macro_hygiene)]

extern crate flame;
#[macro_use] extern crate flamer;

#[flame]
mod flamed_module { .. }

您也可以选择使用 可选依赖。在这种情况下,您的 Cargo.toml 应该包含

[dependencies]
flame = { version = "0.2.2", optional = true }
flamer = { version = "0.3", optional = true }

[features]
default = []
flame_it = ["flame", "flamer"]

并且您的crate根目录应包含

#[cfg(feature = "flame_it")]
extern crate flame;
#[cfg(feature = "flame_it")]
#[macro_use] extern crate flamer;

// as well as the following instead of `#[flame]`
#[cfg_attr(feature = "flame_it", flame)]
// The item to apply `flame` to goes here.

为了支持夜间模块,还需要在crate根目录下添加#![cfg_attr(feature = "flame_it", feature(proc_macro_hygiene))]

#![cfg_attr(feature = "flame_it", feature(proc_macro_hygiene))]

#[cfg(feature = "flame_it")]
extern crate flame;
#[cfg(feature = "flame_it")]
#[macro_use] extern crate flamer;

// as well as the following instead of `#[flame]`
#[cfg_attr(feature = "flame_it", flame)]
mod flamed_module { .. }

然后你应该能够使用#[flame]注释来注释每个项目(遗憾的是,目前不是整个crate;有关更多信息,请参阅自定义内部属性问题)。您还可以使用#[noflame]注释来禁用#[flame]项目的子项的instrumentations。请注意,这只会instrument被注释的方法,不会打印结果。

flame注释还可以接受一个可选参数,指定要加到封装方法名称前缀的字符串。当注释具有相同名称但位于不同模块中的多个方法时,这特别有用。

#[flame("prefix")]
fn method_name() {
    //The corresponding block on the flamegraph will be named "prefix::method_name"
}

完整示例

use std::fs::File;

use flame as f;
use flamer::flame;

#[flame]
fn make_vec(size: usize) -> Vec<u32> {
    // using the original lib is still possible
    let mut res = f::span_of("vec init", || vec![0_u32; size]);
    for x in 0..size {
        res[x] = ((x + 10)/3) as u32;
    }
    let mut waste_time = 0;
    for i in 0..size*10 {
        waste_time += i
    }
    res
}
#[flame]
fn more_computing(i: usize) {
    for x in 0..(i * 100) {
        let mut v = make_vec(x);
        let x = Vec::from(&v[..]);
        for i in 0..v.len() {
            let flip = (v.len() - 1) - i as usize;
            v[i] = x[flip];
        }
    }
}
#[flame]
fn some_computation() {
    for i in 0..15 {
        more_computing(i);
    }
}

#[flame]
fn main() {
    some_computation();
    // in order to create the flamegraph you must call one of the
    // flame::dump_* functions.
    f::dump_html(File::create("flamegraph.html").unwrap()).unwrap();
}

flamegraph

有关输出方式的详细信息,请参阅flame文档

许可证:Apache 2.0

依赖关系

~1.1–1.8MB
~33K SLoC