Skip to content

Commit 218afbe

Browse files
authored
Merge pull request #218 from maxhgerlach/clearer_plot_legend
Make function legend in mprof plot unambiguous
2 parents 959d9fc + 9d896c6 commit 218afbe

3 files changed

Lines changed: 50 additions & 1 deletion

File tree

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ test:
1616
$(PYTHON) test/test_memory_usage.py
1717
$(PYTHON) test/test_precision_import.py
1818
$(PYTHON) test/test_exception.py
19+
$(PYTHON) test/test_mprof.py
1920

2021
develop:
2122
pip install -e .

mprof.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -422,11 +422,12 @@ def plot_file(filename, index=0, timestamps=True, children=True, options=None):
422422
# plot timestamps, if any
423423
if len(ts) > 0 and timestamps:
424424
func_num = 0
425+
f_labels = function_labels(ts.keys())
425426
for f, exec_ts in ts.items():
426427
for execution in exec_ts:
427428
add_brackets(execution[:2], execution[2:], xshift=global_start,
428429
color=all_colors[func_num % len(all_colors)],
429-
label=f.split(".")[-1]
430+
label=f_labels[f]
430431
+ " %.3fs" % (execution[1] - execution[0]), options=options)
431432
func_num += 1
432433

@@ -439,6 +440,33 @@ def plot_file(filename, index=0, timestamps=True, children=True, options=None):
439440
return mprofile
440441

441442

443+
def function_labels(dotted_function_names):
444+
state = {}
445+
446+
def set_state_for(function_names, level):
447+
for fn in function_names:
448+
label = ".".join(fn.split(".")[-level:])
449+
label_state = state.setdefault(label, {"functions": [],
450+
"level": level})
451+
label_state["functions"].append(fn)
452+
453+
set_state_for(dotted_function_names, 1)
454+
455+
while True:
456+
ambiguous_labels = [label for label in state if len(state[label]["functions"]) > 1]
457+
for ambiguous_label in ambiguous_labels:
458+
function_names = state[ambiguous_label]["functions"]
459+
new_level = state[ambiguous_label]["level"] + 1
460+
del state[ambiguous_label]
461+
set_state_for(function_names, new_level)
462+
if len(ambiguous_labels) == 0:
463+
break
464+
465+
fn_to_label = { label_state["functions"][0] : label for label, label_state in state.items() }
466+
467+
return fn_to_label
468+
469+
442470
def plot_action():
443471
def xlim_type(value):
444472
try:

test/test_mprof.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import unittest
2+
3+
import mprof
4+
5+
class Test_function_labels(unittest.TestCase):
6+
def test(self):
7+
expected = {
8+
"x.z": "z",
9+
"x.y": "y",
10+
"x.b": "x.b",
11+
"f.a.b": "f.a.b",
12+
"g.a.b": "g.a.b",
13+
"g.a.c": "a.c",
14+
"b.c": "b.c",
15+
}
16+
result = mprof.function_labels(expected.keys())
17+
self.assertEqual(expected,result)
18+
19+
if __name__ == "__main__":
20+
unittest.main()

0 commit comments

Comments
 (0)