I was thinking that a good default mode would be --flat, which would be in contrast to the tree modes, and would work as follows.
The LEAF data structure is a mapping like
struct Leaves {
/// key: name of top frame
map: HashMap<String, Leaf>
}
struct Leaf {
/// increment this once for every stack trace with this function as the top
/// of the stack. This will be equal to `contexts.values().sum()`, so maybe
/// we don't need it as an explicit value.
total_hits: usize,
/// each time we encounter this leaf, we take the remaining stack frames
/// (i.e., its callers) and we put them in this map with an initial value of 1;
/// if the same callers are already found, then we just bump the usize value.
///
/// This way, we have an idea of where the leaf was called from and how many
/// times from each trace.
contexts: HashMap<Vec<String>, usize>,
}
We populate the data structure above initially based on all the frames
Then we go over all the leaves:
for each one that represents less than N% of total running time:
we pop the leaf and go to each of the contexts:
pop the next top-most frame from the context, and account the time for this leaf over into that context
We keep doing this until all leaves have N%
Then we print the leaves, in order of decreasing total-hits.
I was thinking that a good default mode would be
--flat
, which would be in contrast to the tree modes, and would work as follows.The LEAF data structure is a mapping like
We keep doing this until all leaves have N%
Then we print the leaves, in order of decreasing total-hits.