3 # Copyright (C) 2004-2007, Parrot Foundation.
19 parrotbench - Parrot benchmark
23 parrotbench.pl [options]
26 -b -benchmarks use benchmarks matching regexes (multiple)
27 -c -conf path to configuration file
28 -d -directory path to benchmarks directory
29 -h -? -help display this help and exits
30 -list list available benchmarks and exits
31 -m -method method of time from times()
32 1 $cuser + $csystem from times() (default)
33 2 Real time using POSIX::times()
34 -n -nobench skip benchmarks matching regexes (multiple)
35 -time show times instead of percentage
39 Benchmark Parrot against other interpreters.
43 You must specify paths to executables in a configuration file.
44 That file may be placed as parrotbench.conf in the same directory
45 as parrotbench.pl or otherwise explicitly specified with the
46 -conf option. You may set any command line option in the file with
47 the exception of the configuration file name itself. In the event
48 you have specified an option both in the configuration file and the
49 command line, the command line takes precedence.
51 Here is an example parrotbench.conf:
53 directory = ../../examples/benchmarks
66 exe = ../../parrot -R jit
70 [benchmark perl_585_th]
71 exe = /usr/bin/perl585-th
75 exe = /usr/local/bin/python
84 While every effort was made to ensure this script is portable,
85 it is likely that it will break somewhere.
87 If a benchmark has multiple extensions associated with the same
88 executable, the last one will be used. For instance, with the
89 configuration file above, foo.pir would be selected over foo.pasm
93 Joshua Gatcomb, C<Limbic_Region_2000@Yahoo.com>
95 Originally written by:
97 Sebastian Riedel, C<sri@oook.de>
101 # Create Default Configuration
103 config_file
=> File
::Spec
->catdir( $FindBin::Bin
, 'parrotbench.conf' ),
107 display_help
=> undef,
113 # Read Command Line Options
115 'conf=s' => \
$cfg{config_file
},
116 'directory=s' => \
$cfg{bench_path
},
117 'list' => \
$cfg{list_only
},
118 'time' => \
$cfg{use_times
},
119 'help|?' => \
$cfg{display_help
},
120 'method=s' => \
$cfg{method
},
121 'benchmarks=s' => $cfg{run_bench
},
122 'nobench=s' => $cfg{skip_bench
},
125 # Read Configuration File
126 die 'Unable to access configuration file ', $cfg{config_file
} unless -r
$cfg{config_file
};
128 my $ini = Config
::IniFiles
->new( -file
=> $cfg{config_file
} );
130 # Merge Configuration
131 if ( !defined $cfg{bench_path
} ) {
132 $cfg{bench_path
} = $ini->val( global
=> 'directory' );
134 if ( !defined $cfg{list_only
} ) {
135 $cfg{list_only
} = $ini->val( global
=> 'list' );
137 if ( !defined $cfg{use_times
} ) {
138 $cfg{use_times
} = $ini->val( global
=> 'time' );
140 if ( !defined $cfg{display_help
} ) {
141 $cfg{display_help
} = $ini->val( global
=> 'help' );
144 pod2usage
1 if $cfg{display_help
};
146 if ( !defined $cfg{method
} ) {
147 $cfg{method
} = $ini->val( global
=> 'method', 1 );
150 if ( !@
{ $cfg{run_bench
} } ) {
151 my @regexes = grep defined, $ini->val( regexes
=> 'include' );
152 @
{ $cfg{run_bench
} } = @regexes ?
@regexes : '[\d\D]';
154 if ( !@
{ $cfg{skip_bench
} } ) {
155 my @regexes = grep defined, $ini->val( regexes
=> 'exclude' );
156 @
{ $cfg{skip_bench
} } = @regexes ?
@regexes : '[^\d\D]';
159 # Frequently Used Variables
161 my @section = sort $ini->GroupMembers('benchmark');
162 my @program = map { /^benchmark\s+(.*)$/ } @section;
164 $suffix{$_} = [ map quotemeta, $ini->val( $_, 'type' ) ] for @section;
165 my $ticks = POSIX
::sysconf
(&POSIX
::_SC_CLK_TCK
);
167 1 => sub { my @times = times(); return $times[2] + $times[3] },
168 2 => sub { return ( POSIX
::times() )[0] / $ticks },
171 # Find And Build Benchmarks
174 for my $regex ( @
{ $cfg{run_bench
} } ) {
175 $pass++ and last if /$regex/;
179 for my $regex ( @
{ $cfg{skip_bench
} } ) {
180 $fail++ and last if /$regex/;
183 for my $index ( 0 .. $#section ) {
184 my ( $name, $p, $ext ) = fileparse
( $_, @
{ $suffix{ $section[$index] } } );
186 $bench{$name}{ $program[$index] } = $ext;
189 die "No benchmarks found" if !keys %bench;
191 # List Names Of Benchmarks With Pretty Output
192 if ( $cfg{list_only
} ) {
194 push @rows, [ 'Benchmark', @program ];
195 for my $name ( sort keys %bench ) {
196 push @rows, [ $name, map { $bench{$name}{$_} || '-' } @program ];
199 for ( 0 .. @program ) {
200 for my $row (@rows) {
201 Longest
( $max[$_], length $row->[$_] );
204 for my $col (@rows) {
205 print map { sprintf( "%-$max[$_]s ", $col->[$_] ) } 0 .. $#$col;
211 # Run The Benchmarks With Pretty Output
212 if ( !$cfg{use_times
} && @program < 2 ) {
213 print "WARNING: Switching percentage to time - not enough executables\n";
216 if ( $cfg{use_times
} ) {
217 my $type = $cfg{method
} == 1 ?
'CPU' : 'wall-clock';
218 print "Times are in $type seconds. (lower is better)\n";
221 print "Numbers are relative to the first one. (lower is better)\n";
225 open( my $COPYOUT, ">&STDOUT" ) or die "Unable to copy STDOUT";
226 open( STDOUT
, '>', File
::Spec
->devnull ) or die "Unable to redirect STDOUT";
230 my @max = $cfg{method
} == 1 ?
(5) x
@program : (6) x
@program;
231 Longest
( $max[0], length $_ ) for 'Benchmark', keys %bench;
232 Longest
( $max[ $_ + 1 ], length $program[$_] ) for 0 .. $#program;
233 printf( "%-$max[0]s ", 'Benchmark' );
234 printf( "%-$max[$_ + 1]s ", $program[$_] ) for 0 .. $#program;
236 for my $name ( sort keys %bench ) {
238 printf( "\n%-$max[0]s ", $name );
239 for ( 0 .. $#section ) {
240 my ( $prog, $sect ) = ( $program[$_], $section[$_] );
241 if ( $bench{$name}{$prog} ) {
242 my $start = $Get_Time{ $cfg{method
} }->();
243 system( $ini->val( $sect, 'exe' ) . " "
244 . File
::Spec
->catdir( $cfg{bench_path
}, $name . $bench{$name}{$prog} ) );
245 my $stop = $Get_Time{ $cfg{method
} }->();
246 my $used = $stop - $start;
248 printf( "%-$max[$_ + 1]s ",
250 ?
sprintf( "%.3f", $used )
251 : sprintf( "%d%%", $used / ( $base / 100 ) ) );
254 printf( "%-$max[$_ + 1]s ", '-' );
260 $_[0] = $_[1] and return if !defined $_[0];
261 $_[0] = $_[1] if $_[1] > $_[0];
266 # cperl-indent-level: 4
269 # vim: expandtab shiftwidth=4: