pub struct AccVec<const S: bool, T: TraceValue, C: TraceCount>{ /* private fields */ }Expand description
An AccVec can be used to count and accumulate the times taken to
execute different branches of code, from a common start point. It
uses a Vec internally, and can be dynamically sized; it is
otherwise very similar in operation to an AccArray.
The AccVec is generic on whether to use the CPU-specific architcture timer implementation, the value to accumulate times in (e.g. u64), the value to use to count occurrences (e.g. u32).
An AccVec can be created with a specific capacity - and memory is allocated at this time for that capacity; when it is cleared, the AccVec is emptied, but the contents are not freed.
In addition to the acc_n and acc_n_restart methods of the
AccArray, the AccVec adds acc_push and acc_push_restart, which
append to the current vector (and return the index used).
§Example accumulated times
An AccVec can be used to simply generate an arbitrarily long trace
of accumulated elapsed times (using acc_push):
let mut t = AccVec::<true, u32,()>::default();
t.start();
// do something!
t.acc_push();
// do something more!
t.acc_push();
// do something even more!
t.acc_push();
println!("The first step took {} ticks", t.acc_cnts()[0].0);
println!("The first and second steps took {} ticks", t.acc_cnts()[1].0);
println!("The first thru third steps took {} ticks", t.acc_cnts()[2].0);
§Example individual times
An AccVec can be used to simply generate an arbitrarily long trace
of elapsed times (using acc_push_restart):
let mut t = AccVec::<true, u32, u8>::default();
t.start();
// do something!
t.acc_push_restart();
// do something more!
t.acc_push_restart();
// do something even more!
t.acc_push_restart();
println!("The first step took {} ticks", t.acc_cnts()[0].0);
println!("The second step took {} ticks", t.acc_cnts()[1].0);
println!("The third step took {} ticks", t.acc_cnts()[2].0);
for ac in t.acc_cnts() {
assert_eq!(ac.1, 1, "Each step occurred precisely once");
}§Example accumulate times over many executions
An AccVec can be used to accumulate an arbitrarily long trace
of elapsed times (using acc_push_restart):
let mut t = AccVec::<true, u32, u32>::default();
for i in 0..1000 {
t.start();
if i%3 == 0 {
// do something!
}
t.acc_push_restart();
if i%5 == 0 {
// do something!
}
t.acc_push_restart();
if i%2 == 0 {
// do something!
t.acc_push_restart();
}
}
let ac = t.all_acc_cnts();
assert_eq!(ac.len(), 3, "There are three accumulated values");
println!("The first step took an average of {} ticks", ac[0].0 / ac[0].1);
println!("The second step took an average of {} ticks", ac[1].0 / ac[1].1);
println!("The third step took an average of {} ticks", ac[2].0 / ac[2].1);
assert_eq!(ac[0].1, 1000, "First step occurred 1000 times");
assert_eq!(ac[1].1, 1000, "Second step occurred 1000 times");
assert_eq!(ac[2].1, 500, "*Last* step occurred 500 times");
assert_eq!(t.acc_cnts().len(), 2, "The last iteration did not do the `i%2` push!");§Example accumulate times for different operations over many executions
let mut t = AccVec::<true, u32, u32>::with_capacity(6);
for i in 0..1000 {
t.start();
for j in &["a", "", "bb", "ccc", "dddd", "eeeee", "bb", "ccc"] {
let k = j.chars().count();
t.acc_n_restart(k);
}
}
let ac = t.all_acc_cnts();
assert_eq!(ac.len(), 6, "There are five accumulated values, the given capacity");
for i in 0..6 {
let avg = ac[i].0 / ac[i].1;
println!("Counting {i} characters took an average of {} ticks", avg);
}Implementations§
Source§impl<const S: bool, T, C> AccVec<S, T, C>
impl<const S: bool, T, C> AccVec<S, T, C>
Sourcepub fn with_capacity(n: usize) -> Self
pub fn with_capacity(n: usize) -> Self
Create a new AccVec of a certain size
Sourcepub fn acc_n(&mut self, index: usize)
pub fn acc_n(&mut self, index: usize)
Calculate the ticks elapsed, and accumulate that in the specified entry in the store
If the entry is beyond the capacity of the store, then this does nothing
Sourcepub fn acc_n_restart(&mut self, index: usize)
pub fn acc_n_restart(&mut self, index: usize)
Calculate the ticks elapsed and restart the timer, and accumulate that in the specified entry in the store
If the entry is beyond the capacity of the store, then this just restarts the timer
Sourcepub fn acc_push(&mut self) -> usize
pub fn acc_push(&mut self) -> usize
Calculate the ticks elapsed, and accumulate that in the next entry in the store
This will extend the underlying store if required
Sourcepub fn acc_push_restart(&mut self) -> usize
pub fn acc_push_restart(&mut self) -> usize
Calculate the ticks elapsed and restart the timer, and accumulate that in the next entry in the store
This will extend the underlying store if required
Sourcepub fn all_acc_cnts(&self) -> &[(T, C)]
pub fn all_acc_cnts(&self) -> &[(T, C)]
Return all the accumulated values and counts
This should be used if the acc_n methods are used, but not
acc_push