From: Nicholas Nethercote Date: Mon, 20 Mar 2023 02:58:04 +0000 (+1100) Subject: Improve formatting of percentage columns. X-Git-Tag: VALGRIND_3_21_0~106 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b8a90ee9682b5dbed81d4dd8ee2d7bc3b77eb906;p=thirdparty%2Fvalgrind.git Improve formatting of percentage columns. Currently their width is mostly hard-wired in a quick and dirty fashion. This commit does them properly, so: - all columns are always the right width, even ones with really large percentages - things like `( 1.00%)` are now `(1.00%)` - any percentages that would involve a division by zero now show as `(n/a)` rather than `( 0.00%)` --- diff --git a/cachegrind/cg_annotate.in b/cachegrind/cg_annotate.in index 20969f0f92..e7d094b50d 100755 --- a/cachegrind/cg_annotate.in +++ b/cachegrind/cg_annotate.in @@ -456,10 +456,6 @@ def read_cgout_file() -> tuple[str, str, Events, DictFlfnCc, DictFlDictLineCc, C return (desc, cmd, events, dict_flfn_cc, dict_fl_dict_line_cc, summary_cc) -def safe_perc(m: int, n: int) -> float: - return 0 if n == 0 else m * 100 / n - - class CcPrinter: # Note: every `CcPrinter` gets the same `Events` object. events: Events @@ -467,9 +463,14 @@ class CcPrinter: # Note: every `CcPrinter` gets the same summary CC. summary_cc: Cc - # The width of each event column. For simplicity, its length matches - # `events.events`, even though not all events are necessarily shown. - widths: list[int] + # The width of each event count column. (This column is also used for event + # names.) For simplicity, its length matches `events.events`, even though + # not all events are necessarily shown. + count_widths: list[int] + + # The width of each percentage column. Zero if --show-percs is disabled. + # Its length matches `count_widths`. + perc_widths: list[int] def __init__(self, events: Events, ccs: list[Cc], summary_cc: Cc) -> None: self.events = events @@ -488,61 +489,67 @@ class CcPrinter: min_cc.counts[i] = count # Find maximum width for each column. - self.widths = [0] * len(events.events) + self.count_widths = [0] * len(events.events) + self.perc_widths = [0] * len(events.events) for i, event in enumerate(events.events): - # Get widest of the min and max, accounting for commas that will be - # added, and a possible percentage. - width = max(len(str(min_cc.counts[i])), len(str(max_cc.counts[i]))) - width += (width - 1) // 3 - if args.show_percs: - width += 9 # e.g. " (12.34%)" is 9 chars. + # Get count and perc widths of the min and max CCs. + (min_count, min_perc) = self.count_and_perc(min_cc, i) + (max_count, max_perc) = self.count_and_perc(max_cc, i) - # Account for the event name, too. - self.widths[i] = max(width, len(event)) + # The event name goes in the count column. + self.count_widths[i] = max(len(min_count), len(max_count), len(event)) + self.perc_widths[i] = max(len(min_perc), len(max_perc)) def print_events(self, suffix: str) -> None: for i in self.events.show_indices: - # +1 is for the single space between columns. - print(f"{self.events.events[i]:{self.widths[i] + 1}}", end="") + # The event name goes in the count column. + event = self.events.events[i] + nwidth = self.count_widths[i] + pwidth = self.perc_widths[i] + empty_perc = "" + print(f"{event:<{nwidth}}{empty_perc:>{pwidth}} ", end="") print(suffix) - def print_count(self, i: int, text: str) -> None: - print(f"{text:>{self.widths[i]}}", end=" ") + def print_count_and_perc(self, i: int, count: str, perc: str) -> None: + nwidth = self.count_widths[i] + pwidth = self.perc_widths[i] + print(f"{count:>{nwidth}}{perc:>{pwidth}} ", end="") - def print_cc(self, cc: Cc, suffix: str) -> None: - for i in self.events.show_indices: - nstr = f"{cc.counts[i]:,d}" # commify - if args.show_percs: - if cc.counts[i] != 0: - # Try our best to keep the number fitting into 5 chars. This - # requires dropping a digit after the decimal place if it's - # sufficiently negative (e.g. "-10.0") or positive (e.g. - # "100.0"). Thanks to diffs it's possible to have even more - # extreme values, like "-100.0" or "1000.0"; those rare case - # will end up with slightly wrong indenting, oh well. - p = safe_perc(cc.counts[i], self.summary_cc.counts[i]) - normal = -9.995 < p < 99.995 - perc = f" ({p:5.{2 if normal else 1}f}%)" - else: - # Don't show percentages for "0" entries, it's just clutter. - perc = " " - else: + def count_and_perc(self, cc: Cc, i: int) -> tuple[str, str]: + count = f"{cc.counts[i]:,d}" # commify + if args.show_percs: + if cc.counts[i] == 0: + # Don't show percentages for "0" entries, it's just clutter. perc = "" + else: + summary_count = self.summary_cc.counts[i] + if summary_count == 0: + perc = " (n/a)" + else: + p = cc.counts[i] * 100 / summary_count + # Use just one decimal place for large percentages. + if abs(p) < 100: + w = 2 + else: + w = 1 + perc = f" ({p:.{w}f}%)" + else: + perc = "" - self.print_count(i, nstr + perc) + return (count, perc) + + def print_cc(self, cc: Cc, suffix: str) -> None: + for i in self.events.show_indices: + (count, perc) = self.count_and_perc(cc, i) + self.print_count_and_perc(i, count, perc) print("", suffix) def print_missing_cc(self, suffix: str) -> None: - if args.show_percs: - # Don't show percentages for "." entries, it's just clutter. - text = ". " - else: - text = "." - + # Don't show percentages for "." entries, it's just clutter. for i in self.events.show_indices: - self.print_count(i, text) + self.print_count_and_perc(i, ".", "") print("", suffix) diff --git a/cachegrind/tests/ann2.post.exp b/cachegrind/tests/ann2.post.exp index ac12bf87a4..8d33c9e79a 100644 --- a/cachegrind/tests/ann2.post.exp +++ b/cachegrind/tests/ann2.post.exp @@ -20,28 +20,28 @@ Dw Dr Ir -------------------------------------------------------------------------------- Dw Dr Ir file:function -------------------------------------------------------------------------------- - 3 ( 0.02%) 4,000,004 (98.57%) 5,000,015 (95.61%) a.c:main -4,543 (25.23%) 17,566 ( 0.43%) 47,993 ( 0.92%) /build/glibc-OTsEL5/glibc-2.27/elf/dl-lookup.c:do_lookup_x -3,083 (17.12%) 5,750 ( 0.14%) 28,534 ( 0.55%) /build/glibc-OTsEL5/glibc-2.27/elf/dl-lookup.c:_dl_lookup_symbol_x - 8 ( 0.04%) 5,521 ( 0.14%) 28,136 ( 0.54%) /build/glibc-OTsEL5/glibc-2.27/elf/dl-tunables.c:__GI___tunables_init -2,490 (13.83%) 5,219 ( 0.13%) 21,821 ( 0.42%) /build/glibc-OTsEL5/glibc-2.27/elf/../sysdeps/x86_64/dl-machine.h:_dl_relocate_object - 0 5,158 ( 0.13%) 25,408 ( 0.49%) /build/glibc-OTsEL5/glibc-2.27/string/../sysdeps/x86_64/strcmp.S:strcmp + 3 (0.02%) 4,000,004 (98.57%) 5,000,015 (95.61%) a.c:main +4,543 (25.23%) 17,566 (0.43%) 47,993 (0.92%) /build/glibc-OTsEL5/glibc-2.27/elf/dl-lookup.c:do_lookup_x +3,083 (17.12%) 5,750 (0.14%) 28,534 (0.55%) /build/glibc-OTsEL5/glibc-2.27/elf/dl-lookup.c:_dl_lookup_symbol_x + 8 (0.04%) 5,521 (0.14%) 28,136 (0.54%) /build/glibc-OTsEL5/glibc-2.27/elf/dl-tunables.c:__GI___tunables_init +2,490 (13.83%) 5,219 (0.13%) 21,821 (0.42%) /build/glibc-OTsEL5/glibc-2.27/elf/../sysdeps/x86_64/dl-machine.h:_dl_relocate_object + 0 5,158 (0.13%) 25,408 (0.49%) /build/glibc-OTsEL5/glibc-2.27/string/../sysdeps/x86_64/strcmp.S:strcmp -------------------------------------------------------------------------------- -- User-annotated source: a.c -------------------------------------------------------------------------------- Dw Dr Ir -1 ( 0.01%) 0 2 ( 0.00%) int main(void) { -1 ( 0.01%) 0 1 ( 0.00%) int z = 0; -1 ( 0.01%) 2,000,001 (49.29%) 3,000,004 (57.36%) for (int i = 0; i < 1000000; i++) { -0 2,000,000 (49.29%) 2,000,000 (38.24%) z += i; -. . . } -0 1 ( 0.00%) 6 ( 0.00%) return z % 256; -0 2 ( 0.00%) 2 ( 0.00%) } + 1 (0.01%) 0 2 (0.00%) int main(void) { + 1 (0.01%) 0 1 (0.00%) int z = 0; + 1 (0.01%) 2,000,001 (49.29%) 3,000,004 (57.36%) for (int i = 0; i < 1000000; i++) { + 0 2,000,000 (49.29%) 2,000,000 (38.24%) z += i; + . . . } + 0 1 (0.00%) 6 (0.00%) return z % 256; + 0 2 (0.00%) 2 (0.00%) } -------------------------------------------------------------------------------- Dw Dr Ir -------------------------------------------------------------------------------- -3 ( 0.02%) 4,000,004 (98.57%) 5,000,015 (95.61%) events annotated + 3 (0.02%) 4,000,004 (98.57%) 5,000,015 (95.61%) events annotated diff --git a/cachegrind/tests/ann3.post.exp b/cachegrind/tests/ann3.post.exp index a648bb2e78..52c5b87503 100644 --- a/cachegrind/tests/ann3.post.exp +++ b/cachegrind/tests/ann3.post.exp @@ -1,9 +1,9 @@ -------------------------------------------------------------------------------- Command: ann3 Data file: cgout-test3 -Events recorded: A SomeCount ThisIsAVeryLongEventName -Events shown: A SomeCount ThisIsAVeryLongEventName -Event sort order: A SomeCount ThisIsAVeryLongEventName +Events recorded: A SomeCount VeryLongEventName +Events shown: A SomeCount VeryLongEventName +Event sort order: A SomeCount VeryLongEventName Thresholds: 0.5 100 100 Include dirs: ann3-no-such-dir ann3-no-such-dir-2 @@ -13,53 +13,53 @@ User annotated: ann3-unmentioned.rs Auto-annotation: on -------------------------------------------------------------------------------- -A SomeCount ThisIsAVeryLongEventName +A SomeCount VeryLongEventName -------------------------------------------------------------------------------- -100,000 (100.0%) 100,000 (100.0%) 0 PROGRAM TOTALS +100,000 (100.0%) 100,000 (100.0%) 0 PROGRAM TOTALS -------------------------------------------------------------------------------- -A SomeCount ThisIsAVeryLongEventName file:function +A SomeCount VeryLongEventName file:function -------------------------------------------------------------------------------- -70,491 (70.49%) 90,491 (90.49%) 0 ann3-basic.rs:f0 -15,000 (15.00%) 600 ( 0.60%) 0 ann3-basic.rs:f1 - 9,000 ( 9.00%) 6,000 ( 6.00%) 0 ann3-could-not-be-found.rs:f1 - 2,000 ( 2.00%) 100 ( 0.10%) 0 ann3-basic.rs:f2 - 1,000 ( 1.00%) 500 ( 0.50%) 0 ann3-via-I.rs:f1 - 1,000 ( 1.00%) 300 ( 0.30%) -1,000 ( 0.00%) ann3-past-the-end.rs:f1 --1,000 (-1.00%) 0 0 ann3-negatives.rs:neg3 --1,000 (-1.00%) 0 0 ann3-negatives.rs:neg2 - 1,000 ( 1.00%) 0 0 ann3-more-recent-than-cgout.rs:new - 1,000 ( 1.00%) 0 0 ???:unknown - 500 ( 0.50%) 0 0 ann3-basic.rs:f6 - 500 ( 0.50%) 0 0 ann3-basic.rs:f4 +70,491 (70.49%) 90,491 (90.49%) 0 ann3-basic.rs:f0 +15,000 (15.00%) 600 (0.60%) 0 ann3-basic.rs:f1 + 9,000 (9.00%) 6,000 (6.00%) 0 ann3-could-not-be-found.rs:f1 + 2,000 (2.00%) 100 (0.10%) 0 ann3-basic.rs:f2 + 1,000 (1.00%) 500 (0.50%) 0 ann3-via-I.rs:f1 + 1,000 (1.00%) 300 (0.30%) -1,000 (n/a) ann3-past-the-end.rs:f1 +-1,000 (-1.00%) 0 0 ann3-negatives.rs:neg3 +-1,000 (-1.00%) 0 0 ann3-negatives.rs:neg2 + 1,000 (1.00%) 0 0 ann3-more-recent-than-cgout.rs:new + 1,000 (1.00%) 0 0 ???:unknown + 500 (0.50%) 0 0 ann3-basic.rs:f6 + 500 (0.50%) 0 0 ann3-basic.rs:f4 -------------------------------------------------------------------------------- -- Auto-annotated source: ann3-basic.rs -------------------------------------------------------------------------------- -A SomeCount ThisIsAVeryLongEventName +A SomeCount VeryLongEventName -- line 2 ---------------------------------------- - . . . two - . . . three - 5,000 ( 5.00%) 500 ( 0.50%) 0 four - 5,000 ( 5.00%) 100 ( 0.10%) 0 five - . . . six -70,491 (70.49%) 90,491 (90.49%) 0 seven - . . . eight - 110 ( 0.11%) 9 ( 0.01%) 0 nine - . . . ten - . . . eleven - 200 ( 0.20%) 0 0 twelve - 200 ( 0.20%) 0 0 thirteen - 100 ( 0.10%) 0 0 fourteen - 0 0 0 fifteen - 0 0 0 sixteen - 0 0 0 seventeen - 0 0 0 eighteen - 499 ( 0.50%) 2,000 ( 2.00%) 0 nineteen - 300 ( 0.30%) 0 0 twenty - - 7,100 ( 7.10%) 100 ( 0.10%) 0 + . . . two + . . . three + 5,000 (5.00%) 500 (0.50%) 0 four + 5,000 (5.00%) 100 (0.10%) 0 five + . . . six +70,491 (70.49%) 90,491 (90.49%) 0 seven + . . . eight + 110 (0.11%) 9 (0.01%) 0 nine + . . . ten + . . . eleven + 200 (0.20%) 0 0 twelve + 200 (0.20%) 0 0 thirteen + 100 (0.10%) 0 0 fourteen + 0 0 0 fifteen + 0 0 0 sixteen + 0 0 0 seventeen + 0 0 0 eighteen + 499 (0.50%) 2,000 (2.00%) 0 nineteen + 300 (0.30%) 0 0 twenty + + 7,100 (7.10%) 100 (0.10%) 0 -------------------------------------------------------------------------------- -- Auto-annotated source: ann3-more-recent-than-cgout.rs @@ -71,49 +71,49 @@ A SomeCount ThisIsAVeryLongEventName @ Annotations may not be correct. @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -A SomeCount ThisIsAVeryLongEventName +A SomeCount VeryLongEventName - . . . one -1,000 ( 1.00%) 0 0 two - . . . three - . . . four + . . . one +1,000 (1.00%) 0 0 two + . . . three + . . . four -- line 4 ---------------------------------------- -------------------------------------------------------------------------------- -- Auto-annotated source: ann3-negatives.rs -------------------------------------------------------------------------------- -A SomeCount ThisIsAVeryLongEventName - - 2,000 ( 2.00%) 2,000 ( 2.00%) 2,000 ( 0.00%) one - -1,000 (-1.00%) -1,000 (-1.00%) 0 two - . . . three - . . . four - 999,000 (999.0%) 0 -150,000 ( 0.00%) five --1,000,000 (-1000.0%) 0 150,000 ( 0.00%) six - . . . seven - . . . eight - . . . nine - -10,000 (-10.0%) 0 10 ( 0.00%) ten - 10,000 (10.00%) 0 -20 ( 0.00%) eleven - . . . twelve - . . . thirteen +A SomeCount VeryLongEventName + + 2,000 (2.00%) 2,000 (2.00%) 2,000 (n/a) one + -1,000 (-1.00%) -1,000 (-1.00%) 0 two + . . . three + . . . four + 999,000 (999.0%) 0 -150,000 (n/a) five +-1,000,000 (-1000.0%) 0 150,000 (n/a) six + . . . seven + . . . eight + . . . nine + -10,000 (-10.00%) 0 10 (n/a) ten + 10,000 (10.00%) 0 -20 (n/a) eleven + . . . twelve + . . . thirteen -- line 13 ---------------------------------------- - -2,000 (-2.00%) -1,000 (-1.00%) -990 ( 0.00%) + -2,000 (-2.00%) -1,000 (-1.00%) -990 (n/a) -------------------------------------------------------------------------------- -- Auto-annotated source: ann3-past-the-end.rs -------------------------------------------------------------------------------- -A SomeCount ThisIsAVeryLongEventName +A SomeCount VeryLongEventName -200 ( 0.20%) 100 ( 0.10%) 0 one - . . . two - . . . three +200 (0.20%) 100 (0.10%) 0 one + . . . two + . . . three -- line 3 ---------------------------------------- -- line 18 ---------------------------------------- -300 ( 0.30%) 100 ( 0.10%) 0 -300 ( 0.30%) 100 ( 0.10%) 0 -200 ( 0.20%) 0 -1,000 ( 0.00%) +300 (0.30%) 100 (0.10%) 0 +300 (0.30%) 100 (0.10%) 0 +200 (0.20%) 0 -1,000 (n/a) @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@ WARNING @@ WARNING @@ WARNING @@ WARNING @@ WARNING @@ WARNING @@ WARNING @@ @@ -129,9 +129,9 @@ A SomeCount ThisIsAVeryLongEventName -------------------------------------------------------------------------------- -- Auto-annotated source: ann3-aux/ann3-via-I.rs -------------------------------------------------------------------------------- -A SomeCount ThisIsAVeryLongEventName +A SomeCount VeryLongEventName -1,000 ( 1.00%) 500 ( 0.50%) 0 one +1,000 (1.00%) 500 (0.50%) 0 one -------------------------------------------------------------------------------- The following files chosen for auto-annotation could not be found: @@ -140,7 +140,7 @@ The following files chosen for auto-annotation could not be found: ann3-no-such-file.rs -------------------------------------------------------------------------------- -A SomeCount ThisIsAVeryLongEventName +A SomeCount VeryLongEventName -------------------------------------------------------------------------------- -84,100 (84.10%) 94,700 (94.70%) 1,990 ( 0.00%) events annotated +84,100 (84.10%) 94,700 (94.70%) 1,990 (n/a) events annotated diff --git a/cachegrind/tests/cgout-test3 b/cachegrind/tests/cgout-test3 index 7a3e188a8f..d8023eef1d 100644 --- a/cachegrind/tests/cgout-test3 +++ b/cachegrind/tests/cgout-test3 @@ -1,5 +1,5 @@ cmd: ann3 -events: A SomeCount ThisIsAVeryLongEventName +events: A SomeCount VeryLongEventName # A file testing various things. fl=ann3-basic.rs diff --git a/cachegrind/tests/diff.post.exp b/cachegrind/tests/diff.post.exp index aa88967e26..81fbe3e920 100644 --- a/cachegrind/tests/diff.post.exp +++ b/cachegrind/tests/diff.post.exp @@ -11,25 +11,25 @@ User annotated: Auto-annotation: on -------------------------------------------------------------------------------- -Ir I1mr ILmr Dr D1mr DLmr Dw D1mw DLmw +Ir I1mr ILmr Dr D1mr DLmr Dw D1mw DLmw -------------------------------------------------------------------------------- -5,000,000 (100.0%) 0 0 -2,000,000 (100.0%) 0 0 0 0 0 PROGRAM TOTALS +5,000,000 (100.0%) 0 0 -2,000,000 (100.0%) 0 0 0 0 0 PROGRAM TOTALS -------------------------------------------------------------------------------- -Ir I1mr ILmr Dr D1mr DLmr Dw D1mw DLmw file:function +Ir I1mr ILmr Dr D1mr DLmr Dw D1mw DLmw file:function -------------------------------------------------------------------------------- -5,000,000 (100.0%) 0 0 -2,000,000 (100.0%) 0 0 0 0 0 a.c:main +5,000,000 (100.0%) 0 0 -2,000,000 (100.0%) 0 0 0 0 0 a.c:main -------------------------------------------------------------------------------- -- Auto-annotated source: a.c -------------------------------------------------------------------------------- -Ir I1mr ILmr Dr D1mr DLmr Dw D1mw DLmw +Ir I1mr ILmr Dr D1mr DLmr Dw D1mw DLmw -5,000,000 (100.0%) 0 0 -2,000,000 (100.0%) 0 0 0 0 0 +5,000,000 (100.0%) 0 0 -2,000,000 (100.0%) 0 0 0 0 0 -------------------------------------------------------------------------------- -Ir I1mr ILmr Dr D1mr DLmr Dw D1mw DLmw +Ir I1mr ILmr Dr D1mr DLmr Dw D1mw DLmw -------------------------------------------------------------------------------- -0 0 0 0 0 0 0 0 0 events annotated + 0 0 0 0 0 0 0 0 0 events annotated