Skip to content

Commit b3f7996

Browse files
committed
[benchmark] ReportFormatter: better inline headers
Improve inline headers in `single_table` mode to also print labels for the numeric columns. Sections in the `single_table` are visually distinguished by a separator row preceding the the inline headers. Separated header label styles for git and markdown modes with UPPERCASE and **Bold** formatting respectively. Inlined section template definitions.
1 parent 73b3100 commit b3f7996

File tree

2 files changed

+50
-30
lines changed

2 files changed

+50
-30
lines changed

Diff for: benchmark/scripts/compare_perf_tests.py

+29-27
Original file line numberDiff line numberDiff line change
@@ -547,15 +547,6 @@ def __init__(self, comparator, changes_only,
547547
self.changes_only = changes_only
548548
self.single_table = single_table
549549

550-
MARKDOWN_DETAIL = """
551-
<details {3}>
552-
<summary>{0} ({1})</summary>
553-
{2}
554-
</details>
555-
"""
556-
GIT_DETAIL = """
557-
{0} ({1}): {2}"""
558-
559550
PERFORMANCE_TEST_RESULT_HEADER = ('TEST', 'MIN', 'MAX', 'MEAN', 'MAX_RSS')
560551
RESULT_COMPARISON_HEADER = ('TEST', 'OLD', 'NEW', 'DELTA', 'RATIO')
561552

@@ -589,16 +580,26 @@ def values(result):
589580
def markdown(self):
590581
"""Report results of benchmark comparisons in Markdown format."""
591582
return self._formatted_text(
583+
label_formatter=lambda s: ('**' + s + '**'),
592584
COLUMN_SEPARATOR=' | ',
593-
HEADER_SEPARATOR='---',
594-
DETAIL=self.MARKDOWN_DETAIL)
585+
DELIMITER_ROW=([':---'] + ['---:'] * 4),
586+
SEPARATOR='&nbsp; | | | | \n',
587+
SECTION="""
588+
<details {3}>
589+
<summary>{0} ({1})</summary>
590+
{2}
591+
</details>
592+
""")
595593

596594
def git(self):
597595
"""Report results of benchmark comparisons in 'git' format."""
598596
return self._formatted_text(
597+
label_formatter=lambda s: s.upper(),
599598
COLUMN_SEPARATOR=' ',
600-
HEADER_SEPARATOR=' ',
601-
DETAIL=self.GIT_DETAIL)
599+
DELIMITER_ROW=None,
600+
SEPARATOR='\n',
601+
SECTION="""
602+
{0} ({1}): \n{2}""")
602603

603604
def _column_widths(self):
604605
changed = self.comparator.decreased + self.comparator.increased
@@ -618,24 +619,24 @@ def max_widths(maximum, widths):
618619

619620
return reduce(max_widths, widths, [0] * 5)
620621

621-
def _formatted_text(self, COLUMN_SEPARATOR, HEADER_SEPARATOR, DETAIL):
622+
def _formatted_text(self, label_formatter, COLUMN_SEPARATOR,
623+
DELIMITER_ROW, SEPARATOR, SECTION):
622624
widths = self._column_widths()
623625
self.header_printed = False
624626

625627
def justify_columns(contents):
626628
return [c.ljust(w) for w, c in zip(widths, contents)]
627629

628630
def row(contents):
629-
return COLUMN_SEPARATOR.join(justify_columns(contents)) + ' \n'
631+
return ('' if not contents else
632+
COLUMN_SEPARATOR.join(justify_columns(contents)) + '\n')
630633

631634
def header(title, column_labels):
632-
h = ''
633-
if not self.header_printed:
634-
h = '\n' + row(column_labels)
635-
h += row([':' + HEADER_SEPARATOR] + # left align 1st column
636-
([HEADER_SEPARATOR + ':']) * 4) # right align rest
637-
if self.single_table:
638-
h += row(('**' + title + '**', '', '', '', ''))
635+
labels = (column_labels if not self.single_table else
636+
map(label_formatter, (title, ) + column_labels[1:]))
637+
h = (('' if not self.header_printed else SEPARATOR) +
638+
row(labels) +
639+
(row(DELIMITER_ROW) if not self.header_printed else ''))
639640
if self.single_table and not self.header_printed:
640641
self.header_printed = True
641642
return h
@@ -645,19 +646,20 @@ def format_columns(r, is_strong):
645646
r[:-1] + ('**' + r[-1] + '**', ))
646647

647648
def table(title, results, is_strong=False, is_open=False):
649+
if not results:
650+
return ''
648651
rows = [
649652
row(format_columns(ReportFormatter.values(r), is_strong))
650653
for r in results
651654
]
652655
table = (header(title if self.single_table else '',
653656
ReportFormatter.header_for(results[0])) +
654657
''.join(rows))
655-
return '' if not rows else (
656-
(table if self.single_table else
657-
DETAIL.format(
658-
title, len(results), table, 'open' if is_open else '')))
658+
return (table if self.single_table else
659+
SECTION.format(
660+
title, len(results), table, 'open' if is_open else ''))
659661

660-
return ''.join([
662+
return '\n' + ''.join([
661663
table('Regression', self.comparator.decreased, True, True),
662664
table('Improvement', self.comparator.increased, True),
663665
('' if self.changes_only else

Diff for: benchmark/scripts/test_compare_perf_tests.py

+21-3
Original file line numberDiff line numberDiff line change
@@ -857,15 +857,33 @@ def test_report_only_changes(self):
857857

858858
def test_single_table_report(self):
859859
"""Single table report has bold inline headers and no sections."""
860+
self.tc.removed = [] # test handling empty section
860861
rf = ReportFormatter(self.tc, changes_only=True, single_table=True)
861862
markdown = rf.markdown()
862-
self.assertNotIn('<details', markdown)
863+
self.assertNotIn('<details', markdown) # no sections
864+
self.assertNotIn('\n\n', markdown) # table must not be broken
865+
self.assertNotIn('Removed', markdown)
863866
self.assert_report_contains([
864-
'**Regression**', '**Added**',
865-
'| OLD', '| NEW', '| DELTA', '| RATIO'
867+
'\n**Regression** ',
868+
'| **OLD**', '| **NEW**', '| **DELTA**', '| **RATIO**',
869+
'\n**Added** ',
870+
'| **MIN**', '| **MAX**', '| **MEAN**', '| **MAX_RSS**'
866871
], markdown)
872+
# Single delimiter row:
867873
self.assertIn('\n:---', markdown) # first column is left aligned
868874
self.assertEqual(markdown.count('| ---:'), 4) # other, right aligned
875+
# Separator before every inline header (new section):
876+
self.assertEqual(markdown.count('&nbsp; | | | | '), 2)
877+
878+
git = rf.git()
879+
self.assertNotIn('): \n', git) # no sections
880+
self.assertNotIn('REMOVED', git)
881+
self.assert_report_contains([
882+
'\nREGRESSION ', ' OLD ', ' NEW ', ' DELTA ', ' RATIO ',
883+
'\n\nADDED ', ' MIN ', ' MAX ', ' MEAN ', ' MAX_RSS '
884+
], git)
885+
# Separator before every inline header (new section):
886+
self.assertEqual(git.count('\n\n'), 2)
869887

870888

871889
class Test_parse_args(unittest.TestCase):

0 commit comments

Comments
 (0)