7 个版本
0.5.1 | 2022年5月20日 |
---|---|
0.5.0 | 2021年8月11日 |
0.4.3 | 2021年3月31日 |
0.4.2 | 2021年2月23日 |
0.3.1 | 2021年2月13日 |
#298 in 性能分析
每月下载 180 次
在 2 个库中使用(通过 firestorm)
18KB
344 行
Firestorm是Rust的低开销侵入式火焰图性能分析器。
对于配置,从这里开始 。
对于性能分析,从这里开始 。
Firestorm在底层使用inferno
来显示火焰图。没有他们的贡献,Firestorm将无法实现。
设计原则
Firestorm注重性能。当你编写一个在其类别中速度最快的库时,你需要一个具有相同理想的性能分析器。当Firestorm未启用(默认情况)时,所有调用都会编译为空操作。当Firestorm启用时,它不进行堆分配,并在关键部分中避免尽可能多的工作。
Firestorm无处不在。当应用程序层启用Firestorm进行性能分析时,它会对所有依赖项进行递归启用。这不需要向库中添加功能标志,甚至不需要知道哪些库使用Firestorm。通过避免将Firestorm作为库的公共API的一部分,再加上Firestorm在未使用时编译为空操作的事实...将Firestorm添加到库中应该是一个简单的问题。这是因为随着更多库采用Firestorm,应用程序也会从中受益。
Firestorm提供洞察力。在分析后,Firestorm提供了三种不同的方式来查看数据 - 每种方式都从不同的角度查看运行性能。
配置
首先,在Cargo.toml中将Firestorm添加到您的依赖项中
[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应始终处于使用状态,除非启用,否则不会影响编译时间或性能。
性能分析
要启用性能分析,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
以查看结果。
有三个输出火焰图以不同的方式聚合数据。左上角的下拉菜单切换模式。
时间轴
此模式为每个函数的每次调用显示一个单独的条形图。它被称为“时间轴”,因为数据就像y轴是时间一样。如果想要区分对函数的许多短调用与一次长调用,这将特别有用。这包含了最多的信息,但可能会有些嘈杂。
合并
此模式为调用堆栈中的每条路径显示一个条形图。多个调用可以在单个条形图中显示。这聚合了更多信息。与时间轴模式类似,条形图的宽度表示函数的总时间 - 包括自有时长和被调用函数的时间。
自有时长
此模式将每个函数的自有时长以侧向条形图的形式显示,而不管它是由谁调用的。排序是最耗时的在底部,而“堆栈”与哪个函数调用其他函数无关。遗憾的是,我们的火焰图依赖项不理解这一点,所以请忽略那部分。Firestorm应该改进这里的显示方法,但考虑到它在这个第一版中的有用性,我们决定保留。
依赖项
~3–11MB
~99K SLoC