home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2004 December / PCpro_2004_12.ISO / files / webserver / tsw / TSW_3.4.0.exe / Apache2 / perl / benchmark.pl < prev    next >
Encoding:
Perl Script  |  2001-05-07  |  8.0 KB  |  269 lines

  1. use Benchmark;
  2. use Getopt::Long;
  3. use File::Basename;
  4. use XML::XPath;
  5. use strict;
  6.  
  7. $|++;
  8.  
  9. my @default_drivers = qw(
  10.     LibXSLT
  11.     Sablotron
  12.     );
  13.  
  14. use vars qw(
  15.         $component $iter $ms $kb_in $kb_out $kb_sec $result $ref_size
  16.         );
  17.  
  18. my @getopt_args = (
  19.         'c=s', # config file
  20.         'n=i', # number of benchmark times
  21.         'd=s@', # drivers
  22.         't', # only 1 iteration per test
  23.         'v', # verbose
  24.         'h', # help
  25.         'x', # XSLTMark emulation
  26.         );
  27.  
  28. my %options;
  29.  
  30. Getopt::Long::config("bundling");
  31.  
  32. unless (GetOptions(\%options, @getopt_args)) {
  33.     usage();
  34. }
  35.  
  36. usage() if $options{h};
  37.  
  38. $options{c} ||= 'testcases/default.conf';
  39.  
  40. my $basedir = dirname($options{c});
  41.  
  42. $options{d} ||= [@default_drivers];
  43.  
  44. $options{n} ||= 1;
  45.  
  46. # load drivers
  47. for my $driver (@{$options{d}}) {
  48.     warn "Loading $driver Driver\n" if $options{v};
  49.     require "Driver/$driver.pm";
  50. }
  51.  
  52. # load config
  53. my @config;
  54. open(CONFIG, $options{c}) || die "Can't open config file '$options{c}' : $!";
  55. my $current = {};
  56. while(my $line = <CONFIG>) {
  57.     if ($line =~ /^\s*$/m && %$current) {
  58.         push @config, $current;
  59.         $current = {};
  60.     }
  61.     
  62.     # ignore comments and full line comments
  63.     $line =~ s/#.*$//;
  64.     next unless $line =~ /\S/;
  65.     
  66.     if ($line =~ /^\s*\[(.*)\]\s*$/) {
  67.         $current->{component} = $1;
  68.     }
  69.     elsif ($line =~ /^(.*?)\s*=\s*(.*)$/) {
  70.         $current->{$1} = $2;
  71.     }
  72. }
  73.  
  74. for my $driver (@{$options{d}}) {
  75.     my $pkg = "Driver::${driver}";
  76.     
  77.     $pkg->can('init')->(verbose => $options{v});
  78.     
  79.     $pkg->can('chdir')->($basedir);
  80.     
  81.     print "Testing: $driver\n\n";
  82.  
  83.     print_header();
  84.     
  85.     my %totals;
  86.  
  87.     COMPONENT:
  88.     for my $cmp (@config) {
  89.         warn "Running test: $cmp->{component}\n" if $options{v};
  90.         for (1..$options{n}) {
  91.             $component = $cmp->{component};
  92.             $iter = $ms = $kb_in = $kb_out = $kb_sec = $ref_size = 0;
  93.  
  94.             if ($cmp->{skipdriver} =~ /\b\Q$driver\E\b/) {
  95.                 $result = 'SKIPPED';
  96.                 print_output() unless $cmp->{written};
  97.                 $cmp->{written}++;
  98.                 next COMPONENT;
  99.             }
  100.  
  101.             eval {
  102.                 $pkg->can('load_stylesheet')->($cmp->{stylesheet});
  103.                 $pkg->can('load_input')->($cmp->{input});
  104.  
  105.                 $iter = $cmp->{iterations};
  106.                 $iter = 1 if $options{t};
  107.  
  108.  
  109.                 my $bench = timeit($iter, sub {
  110.                         $pkg->can('run_transform')->($cmp->{output});
  111.                     });
  112.                 
  113.                 my $str = timestr($bench, 'all', '5.4f');
  114.                 
  115.                 if ($str =~ /\((\d+\.\d+)/) {
  116.                     $ms = $1;
  117.                     $ms *= 1000;
  118.                 }
  119.                 
  120.                 $kb_in = (stat($cmp->{input}))[7];
  121.  
  122.                 if ($options{x}) {
  123.                     $kb_in /= 1000;
  124.                 }
  125.                 else {
  126.                     $kb_in += (stat($cmp->{stylesheet}))[7];
  127.                     $kb_in /= 1024;
  128.                 }
  129.                 
  130.                 $kb_in *= $iter;
  131.  
  132.                 $kb_out = (stat($cmp->{output}))[7];
  133.                 $kb_out /= 1024;
  134.                 $kb_out *= $iter;
  135.  
  136.                 die "failed - no output\n" unless $kb_out > 0;
  137.  
  138.                 $kb_sec = ($kb_in + $kb_out) /
  139.                             ( $ms / 500 );
  140.  
  141.                 if ($cmp->{reference}) {
  142.                     $ref_size = (stat($cmp->{reference}))[7];
  143.                     $ref_size /= 1024;
  144.  
  145.                     open(REFERENCE, $cmp->{reference}) || die "Can't open reference '$cmp->{reference}' : $!";
  146.                     open(NEW, $cmp->{output}) || die "Can't open transform output '$cmp->{output}' : $!";
  147.                     local $/;
  148.                     my $ref = <REFERENCE>;
  149.                     my $new = <NEW>;
  150.                     close REFERENCE;
  151.                     close NEW;
  152.                     $new =~ s/\A<\?xml.*?\?>\s*//;
  153.                     $new =~ s/\A<!DOCTYPE.*?>\s*//;
  154.  
  155.                     if (!length($new)) {
  156.                         die "output length failed\n";
  157.                     }
  158.                     if ($new eq $ref) {
  159.                         $result = 'OK';
  160.                     }
  161.                     else {
  162.                         $result = 'CHECK OUTPUT';
  163.                         eval {
  164.                             my $rpp = XML::XPath->new(xml => $ref);
  165.                             my $ppp = XML::XPath::XMLParser->new(xml => $new);
  166.                             my $npp;
  167.                             eval {
  168.                                 $npp = $ppp->parse;
  169.                             };
  170.                             if ($@) {
  171.                                 $npp = $ppp->parse("<norm>$new</norm>");
  172.                             }
  173.                             my @rnodes = $rpp->findnodes('//*');
  174.                             my @nnodes = $npp->findnodes('//*');
  175. #                            warn "ref nodes: ", scalar(@rnodes), "\n";
  176. #                            warn "new nodes: ", scalar(@nnodes), "\n";
  177.                             if (@rnodes == @nnodes) {
  178.                                 $result = 'COUNT OK';
  179.                             }
  180.                         };
  181.                         if ($@) {
  182.                             warn $@ if $options{v};
  183.                         }
  184.                     }
  185.                 }
  186.                 else {
  187.                     $result = 'NO REFERENCE';
  188.                 }
  189.             };
  190.             if ($@) {
  191.                 warn "$component failed: $@" if $options{v};
  192.                 $result = 'ERROR';
  193.             }
  194.             
  195.             if (($result =~ /OK/) || ($result eq 'NO REFERENCE')) {
  196.                 $totals{iter} += $iter;
  197.                 $totals{ms} += $ms;
  198.                 $totals{kb_in} += $kb_in;
  199.                 $totals{kb_out} += $kb_out;
  200.             }
  201.  
  202.             print_output() unless $cmp->{written};
  203.             $cmp->{written}++;
  204.         } # $options{n} loop
  205.         
  206.         delete $cmp->{written};
  207.     } # each component
  208.     
  209.     $pkg->can('shutdown')->();
  210.     
  211.     $component = 'total';
  212.     $iter = $totals{iter};
  213.     $ms = $totals{ms};
  214.     $kb_in = $totals{kb_in};
  215.     $kb_out = $totals{kb_out};
  216.     $kb_sec = ($kb_in + $kb_out) / 
  217.                 ( $ms / 500 );
  218.     $ref_size = 0;
  219.     $result = '';
  220.     print_output();
  221. }
  222.  
  223. sub usage {
  224.     print <<EOT;
  225. usage: $0 [options]
  226.  
  227.     options:
  228.  
  229.         -c <file>   load configuration from <file>
  230.                     defaults to testcases/default.conf
  231.                     
  232.         -n <num>    run each test case <num> times. Default = 1.
  233.         
  234.         -t          only one iteration per test case (note this
  235.                     is different to -n 1)
  236.         
  237.         -d <Driver> test <Driver>. Use multiple -d options to test
  238.                     more than one driver. Defaults are set in this
  239.                     script (the \@default_drivers variable).
  240.         
  241.         -x          XSLTMark emulation. Infuriatingly XSLTMark thinks
  242.                     there are 1000 bytes in a Kilobyte. Someone please
  243.                     tell them some basic computer science...
  244.                     
  245.                     Without this option, this benchmark also includes
  246.                     the size of the stylesheet in the KB In figure.
  247.                     
  248.         -v          be verbose.
  249.  
  250. Copyright 2001 AxKit.com Ltd. This is free software, you may use it and
  251. distribute it under either the GNU GPL Version 2, or under the Perl
  252. Artistic License.
  253.  
  254. EOT
  255.     exit(0);
  256. }
  257.  
  258. sub print_header {
  259.     print STDOUT <<'EOF';
  260. Test Component   Iter    ms   KB In  KB Out      KB/s     Result
  261. ==========================================================================
  262. EOF
  263. }
  264.  
  265. sub print_output {
  266.     printf STDOUT "%-15.15s %5.0d %5.0d %7.0f %7.0f %9.2f   %-15.15s\n",
  267.             $component, $iter, $ms, $kb_in, $kb_out, $kb_sec, $result;
  268. }
  269.