github.com/hanks177/podman/v4@v4.1.3-0.20220613032544-16d90015bc83/hack/parse-localbenchmarks (about)

     1  #!/usr/bin/perl
     2  #
     3  # parse-localbenchmarks - convert localbenchmarks output to CSV
     4  #
     5  # This is a filter. It transforms data from one format to another. Usage:
     6  #
     7  #    $ make localbenchmarks &> mylogfile
     8  #    $ hack/parse-localbenchmarks <mylogfile > benchmarks.csv
     9  #
    10  # To be more precise, this is a very stupid simpleminded filter. It is
    11  # not a complete solution to the benchmarks problem. In particular,
    12  # other tools are still needed to:
    13  #
    14  #    * Actually _run_ the benchmarks in some standard production environment
    15  #    * Run this script on the results
    16  #    * Save results, with identifying tags (datetime, git hash, PR id, ...)
    17  #    * Compare two or more sets of CSVs
    18  #
    19  (our $ME = $0) =~ s|^.*/||;             # script name
    20  
    21  use v5.14;
    22  use utf8;
    23  
    24  # FIXME: add --help. Some day. Not urgent.
    25  die "$ME: This is a filter, not an interactive tool\n"    if -t *STDIN;
    26  
    27  my $n_samples;                          # Number of timing runs (FIXME: unused)
    28  my %results;                            # Timing results
    29  my @benchmarks;                         # Names of benchmarks
    30  my ($type, $testname);                  # Current context
    31  
    32  #
    33  # Pass 1: read in timings
    34  #
    35  while (my $line = <STDIN>) {
    36      # Log will have lots of ginkgo output. The only thing we care about is
    37      # the summary at the end, which will look something like:
    38      #
    39      # * [MEASUREMENT]
    40      # Podman Benchmark Suite
    41      # ....
    42      #  Ran 3 samples:
    43      #  [CPU] podman images:
    44      #    Fastest Time: 0.265s
    45      #    Slowest Time: 0.322s
    46      #    Average Time: 0.302s ± 0.018s
    47      #  [MEM] podman images:
    48      #    Smallest: 44076.0KB
    49      #    Largest: 44616.0KB
    50      #    Average: 44338.7KB ± 171.2KB
    51      #  [CPU] podman push:
    52      #  ....repeat [CPU] and [MEM] for each test
    53      #  --------------------------
    54      #  SSSSSSSSSSSSSSSSSSSSS (and more ginkgo output we don't care about)
    55      #
    56      chomp $line;
    57      next unless $line =~ /^.{1,3}\s+\[MEASUREMENT\]/ .. $line =~ /^-{20,}$/;
    58  
    59      # Trim leading & trailing whitespace
    60      $line =~ s/(^\s+|\s+$)//g;
    61  
    62      # FIXME: we don't actually emit this. What would be a good way to do so?
    63      if ($line =~ /^Ran\s+(\d+)\s+samples/) {
    64          $n_samples = $1;
    65      }
    66  
    67      # e.g., [CPU] podman foo:
    68      elsif ($line =~ /^\[([A-Z]+)\]\s+(\S.*\S):$/) {
    69          ($type, $testname) = ($1, $2);
    70      }
    71  
    72      # e.g., 'Fastest Time: 0.265s'
    73      elsif ($line =~ /^(\S.*?\S):\s+(.*)/) {
    74          my $benchmark = "$type $1";
    75          $results{$testname}{$benchmark} = $2;
    76  
    77          # Keep an ordered list of benchmark names (as in, the order we
    78          # encounter them)
    79          push @benchmarks, $benchmark
    80              unless grep { $_ eq $benchmark } @benchmarks;
    81      }
    82  
    83      else {
    84          warn "Cannot grok '$line'\n"    if $ENV{DEBUG_PARSELOCALBENCHMARKS};
    85      }
    86  }
    87  
    88  #
    89  # Pass 2: write out CSV
    90  #
    91  
    92  # Headings...
    93  print  "\"Test Name\"";
    94  printf ", \"%s\"", $_   for @benchmarks;
    95  print  "\n";
    96  
    97  # ...then data
    98  for my $t (sort keys %results) {
    99      printf "\"%s\"", $t;
   100      for my $benchmark (@benchmarks) {
   101          printf ", \"%s\"", $results{$t}{$benchmark} || '';
   102      }
   103      print "\n";
   104  }