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 }