1#!/usr/bin/perl -T
2
3# examples/benchmark.pl
4#  Compare the ISAAC RNG implementations between each other, and between
5#  other algorithms.
6
7use strict;
8use warnings;
9
10eval {
11  require Benchmark::ProgressBar;
12  Benchmark::ProgressBar->import('cmpthese');
13};
14if ($@) {
15  require Benchmark;
16  Benchmark->import('cmpthese');
17}
18
19=head1 NAME
20
21benchmark.pl - Test performance of various random number generators
22
23=head1 VERSION
24
25Version 1.0
26
27=cut
28
29use version; our $VERSION = qv('1.0');
30
31my $LOOPS    = 10_000; # Number of sequences to generate
32my $NUMTESTS = 2_500; # Numbers to generate each test
33my %TESTING; # modules we're testing
34
35=head1 SYNOPSIS
36
37Usage: benchmark.pl
38
39This script will automatically detect available PRNG algorithms and compare
40them using the Benchmark module. It will keep Pure Perl and C/XS modules
41separate, so as to compare apples to apples.
42
43=head1 DESCRIPTION
44
45This script currently knows about the following modules, and will compare
46them if they are installed.
47
48This module will first compile all of the modules; loading time is also
49benchmarked and compared, but separately from the rest of the operation.
50For object oriented random number algorithms, the constructor is called
51during the benchmark loop, so overhead due to initialization is fairly
52counted too.
53
54It will get 5 million integers from each, so as to provide a good sample
55size. You can tune this, but you'll have to edit the file.
56
57=head2 ALGORITHMS
58
59=over
60
61=item * Math::Random::ISAAC::PP (Perl)
62
63=item * Math::Random::ISAAC::XS (XS/C)
64
65=item * Math::Random::MT (XS/C)
66
67=item * Math::Random::MT::Perl (Perl)
68
69=item * Math::Random::TT800 (XS/C)
70
71=item * Math::Random::random_uniform_integer (XS/C)
72
73=item * Perl core rand() function
74
75=back
76
77=cut
78
79print "Loading modules, please wait...\n";
80load('Math::Random');
81load('Math::Random::ISAAC::XS');
82load('Math::Random::ISAAC::PP');
83load('Math::Random::TT800');
84load('Math::Random::MT');
85load('Math::Random::MT::Perl');
86
87print 'Setting up C/XS number generators... ';
88my $seed = time;
89my $code = {};
90
91# Set up all of the modules we've just loaded
92$code->{'Core'} = sub {
93  my $var;
94  srand($seed);
95  for (1..$NUMTESTS) {
96    $var = rand();
97  }
98};
99
100if ($TESTING{'Math::Random'}) {
101  $code->{'Math::Random'} = sub {
102    my $var;
103    Math::Random::random_set_seed($seed, $seed);
104    for (1..$NUMTESTS) {
105      $var = Math::Random::random_uniform();
106    }
107  };
108}
109
110if ($TESTING{'Math::Random::ISAAC::XS'}) {
111  $code->{'ISAAC::XS'} = sub {
112    my $rng = Math::Random::ISAAC::XS->new($seed);
113    my $var;
114    for (1..$NUMTESTS) {
115      $var = $rng->irand();
116    }
117  };
118}
119
120if ($TESTING{'Math::Random::ISAAC::PP'}) {
121  $code->{'ISAAC::PP'} = sub {
122    my $rng = Math::Random::ISAAC::PP->new($seed);
123    my $var;
124    for (1..$NUMTESTS) {
125      $var = $rng->irand();
126    }
127  };
128}
129
130if ($TESTING{'Math::Random::TT800'}) {
131  $code->{'TT800'} = sub {
132    my $rng = Math::Random::TT800->new($seed);
133    my $var;
134    for (1..$NUMTESTS) {
135      $var = $rng->next_int();
136    }
137  };
138}
139
140if ($TESTING{'Math::Random::MT'}) {
141  $code->{'MT'} = sub {
142    my $rng = Math::Random::MT->new($seed);
143    my $var;
144    for (1..$NUMTESTS) {
145      $var = $rng->rand();
146    }
147  };
148}
149
150if ($TESTING{'Math::Random::MT::Perl'}) {
151  $code->{'MT::Perl'} = sub {
152    my $rng = Math::Random::MT::Perl->new($seed);
153    my $var;
154    for (1..$NUMTESTS) {
155      $var = $rng->rand();
156    }
157  };
158}
159
160print "done.\n";
161
162print "Running comparisons (this might take a while)...\n\n";
163
164cmpthese($LOOPS, $code);
165
166sub load {
167  my ($module) = @_;
168
169  print '  ' . $module . '... ';
170  eval 'use ' . $module;
171  if ($@) {
172    print 'not installed.';
173    $TESTING{$module} = 0;
174  }
175  else {
176    print 'done.';
177    $TESTING{$module} = 1;
178  }
179  print "\n";
180  return;
181}
182
183=head1 AUTHOR
184
185Jonathan Yu E<lt>jawnsy@cpan.orgE<gt>
186
187=head1 SUPPORT
188
189For support details, please look at C<perldoc Math::Random::ISAAC> and
190use the corresponding support methods.
191
192=head1 LICENSE
193
194This has the same copyright and licensing terms as L<Math::Random::ISAAC::XS>.
195
196=head1 SEE ALSO
197
198L<Math::Random::ISAAC::PP>,
199L<Math::Random::ISAAC::XS>,
200L<Math::Random::MT>,
201L<Math::Random::MT::Perl>,
202L<Math::Random::TT800>,
203L<Math::Random::random_uniform_integer>,
204
205=cut
206