3 个版本

0.1.2 2022年5月20日
0.1.1 2021年2月13日
0.1.0 2020年7月1日

#internals 中排名 10

每月下载 48
3 个 crate 中使用 (通过 firestorm-enabled)

MIT 许可

5KB
75

Firestorm 是 Rust 的低开销侵入式火焰图分析器。

Crates.io Documentation MIT licensed

设计原则

开始分析 这里

开始分析 这里

Firestorm 使用 inferno 来显示火焰图。没有他们的贡献,Firestorm 就无法实现。


设计原则

Firestorm 是性能优先的。当你编写的是一个同类中最快的库时,你需要一个拥有相同理念的分析器。当 Firestorm 未启用(默认状态)时,所有调用都会编译为空操作。当 Firestorm 启用时,它不会进行堆分配,并在关键部分避免尽可能多的工作。

Firestorm 是普遍适用的。当 Firestorm 在应用层为分析启用时,它将为所有依赖项启用 - 递归地。这无需向库中添加功能标志,甚至无需知道哪些库使用 Firestorm。通过避免将 Firestorm 作为库的公共 API 的一部分,加上 Firestorm 在未使用时编译为空操作的事实... 将 Firestorm 添加到库中应该是一件自然而然的事情。这是因为随着更多库采用 Firestorm,应用程序也会受益。

Firestorm 提供洞察。分析后,Firestorm 提供三种不同的方式来查看数据 - 每种方式都从不同的角度分析运行性能。


分析

首先,将 Firestorm 添加到 Cargo.toml 中的依赖项

[dependencies]
firestorm = "0.4"

然后,导入 Firestorm 的分析宏。我建议在 crate 的 prelude 模块中这样做。

pub(crate) use firestorm::{
    profile_fn,
    profile_method,
    profile_section
};

最后,在函数中调用宏。

fn fn_name<T>(param: T) {
    // Call profile_fn at the top of your function, specifying the function name.
    // You can optionally add generic parameters, too
    profile_fn!(T, fn_name);

    // If a function is complex, profile a section.
    {
        profile_section!(inner);

        // Optional: manually drop.
        // Section automatically drops when going out of scope.
        drop(inner);
    }
}

fn method_name(&self) {
    // profile_method automatically captures the type of Self
    profile_method!(method_name);
}

分析库的重要提示

  • 不要针对Firestorm的特定版本。例如:不要使用 firestorm = "=0.4.1"。请使用 firestorm = "0.4.1" 代替。这是Firestorm向后兼容策略的重要组成部分。如果需要更新 firestorm-core,所有主要版本都将收到补丁,以确保Firestorm的所有版本都被启用。针对特定版本可能会阻止库共享 firestorm-core 依赖或被间接启用。
  • 不要将firestorm放在 [dev-dependencies] 中。始终将firestorm放在 [dependencies] 中。
  • 不要在库代码中启用任何Firestorm功能,例如 enable_system_time。这样做会阻止Firestorm在不使用时编译为无操作。
  • 不要在功能标志或 [cfg()] 后隐藏Firestorm的使用。Firestorm应始终在使用function be in use,并且除非启用,否则不会影响编译时间或性能。

性能分析

要启用性能分析,Firestorm需要在 Cargo.toml 中指定一个附加功能。

[dependencies]
firestorm = { version="0.4", features=["enable_system_time"] }

分析会话并保存结果

// Runs the function and saves the flamegraph to the supplied directory.
// Make sure this is an empty directory so that no important files are overwritten.
if firestorm::enabled() {
    firestorm::bench("./flames/", instrumented_function).unwrap();
}

运行上述操作后,目标目录中将有 firestorm.html 和一个包含支持文件的 /firestorm 子目录。打开 firestorm.html 来查看结果。

有三个输出火焰图,以不同的方式汇总数据。左上角的下拉菜单用于切换模式。

时间轴

Time Axis

此模式为每个函数的每次调用显示一个单独的条形。它被称为“时间轴”,因为数据就像y轴是时间一样。如果您想区分对函数的许多短调用与一次长调用,这将非常有用。这包含最多的信息,但可能有点嘈杂。

合并

Merged

此模式为调用堆栈中的每条路径显示一个条形。可以在单个条形中显示多个调用。这汇总了更多信息。像时间轴模式一样,条形的宽度表示函数的总时间 - 包括自己的时间和被调用函数的时间。

自己的时间

Own Time

此模式将每个函数的自己的时间作为横向条形图显示,而不考虑它被调用的情况。排序是最耗时的函数在底部,而“堆栈”与哪个函数调用其他函数无关。不幸的是,我们的火焰图依赖项不理解这一点,所以请忽略那部分。Firestorm应改进这里的显示方法,但考虑到它的实用性,第一版中不能省略。


lib.rs:

firestorm-core的想法是尝试创建一个小API子集,以便多个Firestorm版本可以共享常见数据,即使它们之间可能存在向后不兼容的API更改。这可能还不够,但这是一个朝着这个方向迈出的步骤。

依赖项

~6KB