15 个版本
0.2.12 | 2022 年 12 月 17 日 |
---|---|
0.2.11 | 2022 年 12 月 17 日 |
0.1.2 | 2022 年 12 月 13 日 |
#142 in 性能分析
40 次每月下载
11KB
141 行
一套用于功能分析的宏
包含一些方便的宏来分析函数执行,如 count
来了解函数被调用的次数,trace
来记录函数的进入/退出及其参数,以及用于纯函数缓存的 cache
。
特性
特性 | 描述 | 其他依赖 |
---|---|---|
count |
提供 count! 宏,以获取函数被调用的次数 |
无 |
trace |
在标记函数的进入/退出时打印并显示其参数 | 无 |
cache |
为标记函数实现记忆化 | once_cell 和 hashbrown |
time |
在函数内打印经过的时间 | 无 |
depth |
根据“函数深度”添加缩进格式化 | 无 |
visible |
改变缓存存储和计数器的可见性 | 无 |
可以在属性声明中禁止、强制或设置每个特性的默认值(默认值是通过特性设置的)。例如
// `cache` and `visible` will not be implemented
// `count` will obligatory be implemented
// `time`/`depth` will be implemented if the feature `time`/`depth` is enable
#[moneta_fn::moneta(cache = "forbid", visible = "forbid", count = "force", time = "default")]
fn foo(a: u8) -> u8 {
unimplemented!()
}
类型依赖
在函数中启用时,cache
需要所有参数实现 Debug
特性和返回类型的 Clone
。
等等... 为什么参数需要 Debug
,而不是 Clone
呢?
考虑以下场景
#[moneta_fn::moneta]
fn foo<'a, T>(lhs: &'a T, rhs: &'a T) -> T {
unimplemented!()
}
很难创建具有泛型键和生命周期的缓存存储,一旦它不能被解析为全局 RwLock
的等效格式。
此外,它还允许对关联类型进行一些优化
#[moneta_fn::moneta]
fn foo<T: AsRef<str> + Debug>(lhs: T, rhs: T) -> T {
unimplemented!()
}
我不想在发布构建中使用 trace/count/cache
。我该如何禁用它?
目前还没有一种很好的方法来在不同的配置文件中启用/禁用特定特性。您需要将 default-features
设置为 false
并定义您想要的特性。例如
[dependencies]
moneta_fn = { version = "*", default-features = false, features = ["cache", "count", "time"] }
另一种方法是设置默认特性。
[dependencies]
moneta_fn = { version = "*", default-features = false, features = ["cache", "count", "time"] }
[features]
default = ["debug_mode"]
debug_mode = ["moneta_fn/trace"]
当使用配置文件发布编译时,使用 --no-default-features
cargo build --release --no-default-features
我该如何只为一个函数启用/禁用 trace/count/cache
?
将 trace
/count
/cache
设置为 force
/forbid
#[moneta_fn::moneta(cache = "forbid")] // Will not update cache storage
fn foo(a: u8) -> u8 {
unimplemented!()
}
宏定义
存在宏来管理实现变量
宏定义 | 外部特性 | 描述 |
---|---|---|
count |
count |
返回一个包含函数被调用次数的 usize |
get_counter |
count |
返回对应函数的 std::sync::AtomicUsize 计数器 |
reset_count |
count |
将函数计数设置为 0 |
get_cache |
cache |
返回包含函数返回类型的 once_cell::Lazy<std::sync::RwLock<hashbrown::HashMap<String, T>>> 缓存存储,其中 T 是函数的返回类型 |
所有这些宏都需要一个包含函数全局路径的参数。例如
#[moneta_fn::moneta]
fn foo() {
unimplemented!()
}
pub mod bar {
#[moneta_fn:moneta]
pub fn baz() {
unimplemented!()
}
}
assert!(get_cache(foo).read().unwrap().is_empty())
assert_eq!(count!(bar::baz), 0)
当外部特性被禁用时,宏调用会中断吗?
不会。计数或缓存将不会更新。
依赖项
~3.5MB
~64K SLoC