scripts: Fully connected graph in stack.py, no more recursive folding
This makes -D/--define more useful in stack.py/perf.py/perfbd.py by no longer hiding undfined children entries. For example: $ ./scripts/stack.py lfs.ci lfs_util.ci -Dfunction=lfsr_mount -t function frame limit lfsr_mount 96 2816 |-> lfsr_fs_gc 80 2720 |-> lfsr_mtree_gc 176 2640 |-> lfsr_mdir_commit 576 2464 ... snip ... Now shows all functions in the hot path of lfsr_mount, where before it would only show functions in the hot path of lfsr_mount that were also _named_ lfsr_mount. The previous behavior was technically not wrong... but not very useful (and confusing). --- This was actually quite a bit annoying to get working because of the possibility of function call cycles. I ended up turning stack.py's result type into a fully connected graph, which only works because Python has a cycle detector. (Actually this script is so short-lived we probably wouldn't care if this leaked memory.) A nice side effect of this is now all the recursive scripts (stack.py, perf.py, and perfbd.py) share the same internal result representation and recursive printing logic, which is probably a good thing.
This commit is contained in:
+8
-16
@@ -621,15 +621,6 @@ def fold(Result, results, by=None, defines=[]):
|
||||
for name, rs in folding.items():
|
||||
folded.append(sum(rs[1:], start=rs[0]))
|
||||
|
||||
# fold recursively
|
||||
folded_ = []
|
||||
for r in folded:
|
||||
folded_.append(r._replace(children=fold(
|
||||
Result, r.children,
|
||||
by=by,
|
||||
defines=defines)))
|
||||
folded = folded_
|
||||
|
||||
return folded
|
||||
|
||||
def table(Result, results, diff_results=None, *,
|
||||
@@ -802,7 +793,8 @@ def table(Result, results, diff_results=None, *,
|
||||
depth_ = 2
|
||||
elif m.isinf(depth_):
|
||||
def rec_depth(results_, seen=set()):
|
||||
# rebuild our tables at each layer
|
||||
# build the children table at each layer
|
||||
results_ = fold(Result, results_, by=by)
|
||||
table_ = {
|
||||
','.join(str(getattr(r, k) or '') for k in by): r
|
||||
for r in results_}
|
||||
@@ -835,7 +827,8 @@ def table(Result, results, diff_results=None, *,
|
||||
if hot:
|
||||
def recurse(results_, depth_, seen=set(),
|
||||
prefixes=('', '', '', '')):
|
||||
# rebuild our tables at each layer
|
||||
# build the children table at each layer
|
||||
results_ = fold(Result, results_, by=by)
|
||||
table_ = {
|
||||
','.join(str(getattr(r, k) or '') for k in by): r
|
||||
for r in results_}
|
||||
@@ -893,14 +886,14 @@ def table(Result, results, diff_results=None, *,
|
||||
else:
|
||||
def recurse(results_, depth_, seen=set(),
|
||||
prefixes=('', '', '', '')):
|
||||
# rebuild our tables at each layer
|
||||
# build the children table at each layer
|
||||
results_ = fold(Result, results_, by=by)
|
||||
table_ = {
|
||||
','.join(str(getattr(r, k) or '') for k in by): r
|
||||
for r in results_}
|
||||
names_ = list(table_.keys())
|
||||
|
||||
# sort again at each layer, keep in mind the numbers are
|
||||
# changing as we descend
|
||||
# sort the children layer
|
||||
names_.sort()
|
||||
if sort:
|
||||
for k, reverse in reversed(sort):
|
||||
@@ -948,8 +941,7 @@ def table(Result, results, diff_results=None, *,
|
||||
prefixes[2+is_last] + "| ",
|
||||
prefixes[2+is_last] + " "))
|
||||
|
||||
# we have enough going on with diffing to make the top layer
|
||||
# a special case
|
||||
# the top layer is a bit of a special case
|
||||
for name, line in zip(names, lines[1:-1]):
|
||||
print('%-*s %s' % (
|
||||
widths[0], line[0][0],
|
||||
|
||||
Reference in New Issue
Block a user