5 个版本 (重大更改)
0.5.0 | 2019年2月26日 |
---|---|
0.4.0 | 2019年2月22日 |
0.3.0 | 2019年2月22日 |
0.2.0 | 2019年2月22日 |
0.1.0 | 2019年2月21日 |
#9 in #purpose
19KB
343 行
用于轻松计数的调试工具
这可以用来收集有关不同代码路径执行频率的统计数据。
开销
计数器相对开销较小,但不是免费的(使用静态字符串切片作为键查找 FxHashMap 的成本)。使用计数器可能会影响性能测量。
优化
当使用类型 DebugCounters
和 DebugTable
而不是 Counters
和 Table
时,如果没有启用 debug_counters
功能标志,实现为空。这样可以在发布和配置文件构建配置中放弃其开销,同时保留计数事件代码。
模拟特质实现
为了嵌入实现 Serialize
和 Deserialize
的结构,Counters
和 DebugCounters
具有可以启用 dummy_serialization
功能标志的模拟特质实现。
类似地,以下特质也有模拟实现
Eq
,PartialEq
: 总是返回 true。Hash
: 不贡献哈希值。
这些模拟实现旨在不改变嵌入结构的行怛。
示例
在下面的示例中,我们有一个函数 do_the_thing
,我们确定它是昂贵的(使用分析器)。我们希望了解该函数运行得多频繁以及我们经常采取慢速和快速路径。
use counters::Counters;
use counters::filters::*;
struct Foo {
counters: Counters,
}
impl Foo {
// This method is not mutable (&self), however we can still update
// the counters because they use internal mutability.
fn do_the_thing(&self, n: u32) -> u32 {
self.counters.event("do_the_thing");
if n % 17 == 0 {
self.counters.event("fast path A");
return self.foo();
}
if n % 56 == 0 {
self.counters.event("fast path B");
return self.bar();
}
self.counters.event("slow path");
return self.baz();
}
fn do_all_of_the_things(&mut self) {
self.counters.reset_all();
for i in 0..100 {
self.do_the_thing(i);
}
// We can use filters to accumulate the values of several counters.
let total_fast_path = self.counters.accumulate(Contains("fast path"));
let slow_path = self.counters.get("do_the_thing") - total_fast_path;
// Set the value of a counter.
self.counters.set("slow path", slow_path);
// This prints the following to stdout:
// slow path: 93
// fast path A: 6
// fast path B: 1
// do_the_thing: 100
self.counters.print_to_stdout(All);
}
// Let's pretend the methods below do interesting things...
fn foo(&self) -> u32 { 0 }
fn bar(&self) -> u32 { 0 }
fn baz(&self) -> u32 { 0 }
}
依赖关系
~96–295KB