1#! /usr/bin/perl 2## 3## vi:ts=4:et 4## 5##---------------------------------------------------------------------------## 6## 7## Author: 8## Markus F.X.J. Oberhumer <markus@oberhumer.com> 9## 10## Description: 11## Convert the output of the LZO lzotest program into a nice table. 12## 13## Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer 14## 15##---------------------------------------------------------------------------## 16 17$PROG = $0; 18require 'ctime.pl'; 19 20# 21# get options 22# 23 24while ($_ = $ARGV[ $[ ], /^-/) { 25 shift(@ARGV); 26 /^--$/ && ($opt_last = 1, last); 27 28 /^--sort=name/ && ($opt_sort_summary_by_name++, next); 29 /^--sort=ratio/ && ($opt_sort_summary_by_ratio++, next); 30 /^-s/ && ($opt_summary_only++, next); 31 /^-t/ && ($opt_clear_time++, next); 32} 33 34 35$alg = ''; 36$sep = "+" . ("-" x 76) . "+\n"; 37 38$block_size = -1; 39 40$n = 0; 41@algs = (); 42%average = (); 43%total = (); 44 45$lzo_version_string = ''; 46$lzo_version_date = ''; 47 48 49# /*********************************************************************** 50# // 51# ************************************************************************/ 52 53while (<>) { 54 55 if (/(^|\s)(\d+)\s+block\-size/i) { 56 if ($block_size < 0) { 57 $block_size = $2; 58 &intro($block_size); 59 } elsif ($block_size != $2) { 60 die "$PROG: block-size: $block_size != $2\n"; 61 } 62 next; 63 } 64 65 if (/^\s*LZO\s.*library\s+\(v\s*([\w\.\s]+)\s*\,\s*([^\)]+)\)/) { 66 $lzo_version_string = $1; 67 $lzo_version_date = $2; 68 next; 69 } 70 71 if (/^\s*(\S+(\s+\[\S+\])?)\s*(\|.*\|)\s*$/i) { 72 if ($1 ne $alg) { 73 &footer($1); 74 &header($1); 75 } 76 $line = $3; 77 &stats(*line); 78 print "$line\n" if (!$opt_summary_only); 79 } 80} 81&footer($1); 82 83&summary(); 84 85exit(0); 86 87 88# /*********************************************************************** 89# // 90# ************************************************************************/ 91 92sub stats { 93 local (*l) = @_; 94 local ($x1, $x2, $x3, $x4, $x5, $x6, $x7, $x8); 95 96 if ($l !~ /^\|\s*(.+?)\s+(\d+)\s+(\d+)\s+(\d+)\s+([\d\.]+\s+)?([\d\.]+\s+)?([\d\.]+)\s+([\d\.]+)\s*\|/) { 97 die $_; 98 } 99 100 $n++; 101 102 $x1 = $1; $x2 = $2; $x3 = $3; $x4 = $4; 103 $x5 = ($x2 > 0) ? $x4 * 100.0 / $x2 : 0.0; 104 $x6 = ($x2 > 0) ? $x4 * 8.0 / $x2 : 0.0; 105 $x7 = $7; $x8 = $8; 106 107 # convert from kB/s to MB/s (for old versions of lzotest) 108 if ($x7 =~ /\.\d\d$/) { $x7 = $x7 / 1000.0; } 109 if ($x8 =~ /\.\d\d$/) { $x8 = $x8 / 1000.0; } 110 111 if ($opt_clear_time) { 112 $x7 = $x8 = 0.0; 113 } 114 115 $s[0] += $x2; 116 $s[1] += $x3; 117 $s[2] += $x4; 118 $s[3] += $x5; 119 $s[4] += $x6; 120 if ($x7 > 0) { 121 $s[5] += 1.0 / $x7; $sn[5] += 1; 122 } 123 if ($x8 > 0) { 124 $s[6] += 1.0/ $x8; $sn[6] += 1; 125 } 126 127 $x1 =~ s/\s+$//; 128 $l = sprintf("| %-14s %10d %5d %9d %6.1f %5.2f %9.3f %9.3f |", 129 $x1, $x2, $x3, $x4, $x5, $x6, $x7, $x8); 130} 131 132 133# /*********************************************************************** 134# // 135# ************************************************************************/ 136 137sub header { 138 local ($t) = @_; 139 140 $alg = $t; 141 142 # reset stats 143 $n = 0; 144 @s = (0, 0, 0, 0.0, 0.0, 0.0, 0.0); 145 @sn = (0, 0, 0, 0, 0, 0, 0); 146 147 return if $opt_summary_only; 148 149 print "\n$alg\n\n"; 150 print $sep; 151print <<EndOfString; 152| File Name Length CxB ComLen Ratio% Bits Com MB/s Dec MB/s | 153| --------- ------ --- ------ ----- ---- -------- -------- | 154EndOfString 155} 156 157 158# /*********************************************************************** 159# // 160# ************************************************************************/ 161 162sub footer { 163 local ($t) = @_; 164 local ($shm5, $shm6); 165 166 return unless $alg; 167 die if $n <= 0; 168 die if $s[0] <= 0; 169 170 # harmonic mean 171 $shm5 = $s[5] > 0 ? $sn[5] / $s[5] : 0.0; 172 $shm6 = $s[6] > 0 ? $sn[6] / $s[6] : 0.0; 173 174 push(@algs,$alg); 175 176 $average{$alg} = 177 sprintf("| %-14s %10d %5d %9d %6.1f %5.2f %9.3f %9.3f |\n", 178 "Average", $s[0]/$n, $s[1]/$n, $s[2]/$n, 179 $s[3]/$n, $s[4]/$n, 180 $shm5, $shm6); 181 182 $total{$alg} = 183 sprintf("| %-14s %10d %5d %9d %6.1f %5.2f %9.3f %9.3f |\n", 184 "Total", $s[0], $s[1], $s[2], 185 $s[2]/$s[0]*100, $s[2]/$s[0]*8, 186 $shm5, $shm6); 187 188 return if $opt_summary_only; 189 190 print $sep; 191 print $average{$alg}; 192 print $total{$alg}; 193 print $sep, "\n"; 194} 195 196 197# /*********************************************************************** 198# // 199# ************************************************************************/ 200 201$sort_mode = 0; 202 203sub cmp_by_ratio { 204 local ($aa, $bb); 205 206 if ($sort_mode == 0) { 207 $aa = $average{$a}; 208 $bb = $average{$b}; 209 } elsif ($sort_mode == 1) { 210 $aa = $total{$a}; 211 $bb = $total{$b}; 212 } else { 213 die; 214 } 215 216 ($aa =~ m%^\s*\|\s+\S+\s+\d+\s+\d+\s+\d+\s+(\S+)%) || die; 217 $aa = $1; 218 ($bb =~ m%^\s*\|\s+\S+\s+\d+\s+\d+\s+\d+\s+(\S+)%) || die; 219 $bb = $1; 220 221 # $aa < $bb; 222 $aa cmp $bb; 223} 224 225 226# /*********************************************************************** 227# // 228# ************************************************************************/ 229 230sub summary { 231 local ($l); 232 local (@k); 233 234 $sort_mode = 0; 235 if ($opt_sort_summary_by_name) { 236 @k = sort(@algs); 237 } elsif ($opt_sort_summary_by_ratio) { 238 @k = sort(cmp_by_ratio @algs); 239 } else { 240 @k = @algs; 241 } 242 243 print "\n\n"; 244 print "Summary of average values\n\n"; 245 print $sep; 246print <<EndOfString; 247| Algorithm Length CxB ComLen Ratio% Bits Com MB/s Dec MB/s | 248| --------- ------ --- ------ ----- ---- -------- -------- | 249EndOfString 250 251 for (@k) { 252 $l = $average{$_}; 253 $l =~ s/Average[\s]{7}/sprintf("%-14s",$_)/e; 254 print $l; 255 } 256 print $sep; 257 258 259 260 $sort_mode = 1; 261 if ($opt_sort_summary_by_name) { 262 @k = sort(@algs); 263 } elsif ($opt_sort_summary_by_ratio) { 264 @k = sort(cmp_by_ratio @algs); 265 } else { 266 @k = @algs; 267 } 268 269 print "\n\n"; 270 print "Summary of total values\n\n"; 271 print $sep; 272print <<EndOfString; 273| Algorithm Length CxB ComLen Ratio% Bits Com MB/s Dec MB/s | 274| --------- ------ --- ------ ----- ---- -------- -------- | 275EndOfString 276 277 for (@k) { 278 $l = $total{$_}; 279 $l =~ s/Total[\s]{9}/sprintf("%-14s",$_)/e; 280 print $l; 281 } 282 print $sep; 283} 284 285 286# /*********************************************************************** 287# // 288# ************************************************************************/ 289 290sub intro { 291 local ($bs) = @_; 292 local ($v, $t, $x); 293 local ($u, $uname_m, $uname_s, $uname_r); 294 295 $t = &ctime(time); chop($t); 296 $t = sprintf("%-55s |", $t); 297 298 $v=''; 299 if ($lzo_version_string) { 300 $v = $lzo_version_string; 301 $v .= ', ' . $lzo_version_date if $lzo_version_date; 302 $v = sprintf("%-55s |", $v); 303 $v = sprintf("| LZO version : %s\n", $v); 304 } 305 306 if ($bs % 1024 == 0) { 307 $x = sprintf("%d (= %d kB)", $bs, $bs / 1024); 308 } else { 309 $x = sprintf("%d (= %.3f kB)", $bs, $bs / 1024.0); 310 } 311 $x = sprintf("%-55s |", $x); 312 313 $u=''; 314 if (1 == 1) { 315 $uname_s = `uname -s`; $uname_s =~ s/^\s+//; $uname_s =~ s/\s+$//; 316 $uname_r = `uname -r`; $uname_r =~ s/^\s+//; $uname_r =~ s/\s+$//; 317 $uname_m = `uname -m`; $uname_m =~ s/^\s+//; $uname_m =~ s/\s+$//; 318 if ($uname_s && $uname_m) { 319 $u = $uname_s; 320 $u .= ' ' . $uname_r if $uname_r; 321 $u .= ' ' . $uname_m; 322 $u = sprintf("%-55s |", $u); 323 $u = sprintf("| Operating system : %s\n", $u); 324 } 325 } 326 print <<EndOfString; 327 328+----------------------------------------------------------------------------+ 329| DATA COMPRESSION TEST | 330| ===================== | 331| Time of run : $t 332$v$u| Context length : $x 333+----------------------------------------------------------------------------+ 334 335 336Notes: 337- CxB is the number of independent blocks a file was splitted 338- MB/s is the speed measured in 1,000,000 uncompressed bytes per second 339- all averages are calculated from the un-rounded values 340- the average ratio & bits are calculated by the arithmetic mean 341- the average speed is calculated by the harmonic mean 342 343 344EndOfString 345} 346 347__END__ 348 349 350### insert something like this after 'Time of run': 351 352| Hardware : Intel Pentium 133, 64 MB RAM, 256 kB Cache | 353| Operating system : MS-DOS 7.10, HIMEM.SYS 3.95, DOS/4GW 1.97 | 354| Compiler : Watcom C32 10.5 | 355| Compiler flags : -mf -5r -oneatx | 356| Test suite : Calgary Corpus Suite | 357| Files in suite : 14 | 358| Timing accuracy : One part in 100 | 359 360 361