3 个版本

0.1.2 2024年3月30日
0.1.1 2024年3月30日
0.1.0 2024年3月30日

#2395开发工具

每月 32 次下载
2 个 crate 中使用 (通过 profi)

MIT 许可证

13KB
65

Profi

适用于单线程和多线程应用程序的简单分析器。

记录作用域结束所需的时间,并在程序退出时打印计时结果。

每次测量的开销约为 ~25ns-50ns,因此不应影响基准测试。
运行 基准测试 示例以查看您的机器上的开销。

设置

profienable 功能控制,默认情况下该功能处于激活状态。
当禁用时,所有宏和方法都将变为无操作,从而对您的代码没有任何影响。

要禁用它,请将 default-features = false 添加到您的 Cargo.toml 中的 profi 依赖项中。

为了方便,您还可以添加一个自定义功能

[dependencies]
profi = { version = "*", default-features = false }

[features]
prof = ["profi/enable"]

并用 cargo run --release --features prof 运行它

如果您使用 rayon,请启用 rayon 功能

用法

有关更多用法示例,请参阅 examples

基本用法

use profi::{prof, print_on_exit};

fn main() {
 // Prints the timings to stdout when the program exits
 // Always put at the top of the main function to ensure it's dropped last
 //
 // An implicit `main` guard is created to profile the whole application
 print_on_exit!();

 // Sleep for a bit to simulate some work
 std::thread::sleep(std::time::Duration::from_millis(200));
}
┌──────────────┬────────────────────┬───────────┬──────────────┬───────┐
│ Name         ┆ % Application Time ┆ Real Time ┆ Average time ┆ Calls │
╞══════════════╪════════════════════╪═══════════╪══════════════╪═══════╡
│ simple::main ┆ 100.00%            ┆ 200.13ms  ┆       -      ┆     1 │
└──────────────┴────────────────────┴───────────┴──────────────┴───────┘

循环

use profi::{prof, print_on_exit};

fn main() {
  print_on_exit!();

  for _ in 0..100 {
      prof!(iteration);
      std::thread::sleep(std::time::Duration::from_millis(10));
  }
}
┌────────────┬────────────────────┬───────────┬──────────────┬───────┐
│ Name       ┆ % Application Time ┆ Real Time ┆ Average time ┆ Calls │
╞════════════╪════════════════════╪═══════════╪══════════════╪═══════╡
│ loop::main ┆ 100.00%            ┆ 1.01s     ┆       -      ┆     1 │
├╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┤
│ iteration  ┆ 99.99%             ┆ 1.01s     ┆ 10.10ms/call ┆   100 │
└────────────┴────────────────────┴───────────┴──────────────┴───────┘

多个线程

use profi::{print_on_exit, prof_guard};

fn do_work(i: usize) {
    // Need to bind it to a variable to ensure it isn't dropped before sleeping
    let _guard = if i < 6 {
        prof_guard!("6 first")
    } else {
        prof_guard!("4 last")
    };
    std::thread::sleep(std::time::Duration::from_millis(10));
    // The guard goes out of scope here
}

fn main() {
    print_on_exit!();
    
    // Spawn 10 threads
    std::thread::scope(|s| {
        for i in 0..10 {
            s.spawn(move || {
                do_work(i);
            });
        }
    });
}
┌───────────────┬────────────────────┬───────────┬────────────┬──────────┬──────────────┬───────┐
│ Name          ┆ % Application Time ┆ Real Time ┆ % CPU Time ┆ CPU Time ┆ Average time ┆ Calls │
╞═══════════════╪════════════════════╪═══════════╪════════════╪══════════╪══════════════╪═══════╡
│ threads::main ┆ 100.00%            ┆ 10.48ms   ┆ 9.43%      ┆ 10.48ms  ┆       -      ┆     1 │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┤
│ 6 first       ┆ 96.42%             ┆ 10.11ms   ┆ 54.38%     ┆ 60.44ms  ┆ 10.08ms/call ┆     6 │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┤
│ 4 last        ┆ 95.93%             ┆ 10.06ms   ┆ 36.19%     ┆ 40.22ms  ┆ 10.06ms/call ┆     4 │
└───────────────┴────────────────────┴───────────┴────────────┴──────────┴──────────────┴───────┘

"CPU 时间" 是所有线程在该作用域上花费的总时间。

例如,"6 first" 的 "CPU 时间" 为 60 毫秒,因为每个线程等待 10ms,程序创建了六个这样的线程。

属性

启用 attributes 功能以在函数上使用 profile 属性。
这将向函数的开始处添加一个守卫。

use profi::profile;

#[profile]
fn anotated() { /* ... */ }

功能

名称 描述
enable 激活分析,如果不激活,所有宏都变为无操作
属性 启用 #[prof]
deep-hierarchy 默认情况下,profi 会合并函数的所有使用,使用此功能可禁用此行为。
有关更多信息,请参阅 nested 示例
nightly 启用仅夜间的优化(目前未使用)
rayon 如果使用 rayon,则必要

依赖关系

约1.5MB
约24K SLoC