]> git.vpit.fr Git - perl/modules/Scalar-Vec-Util.git/blob - samples/bench.pl
Add a fairer 'eq' benchmark with regards to Bit::Vector
[perl/modules/Scalar-Vec-Util.git] / samples / bench.pl
1 #!/usr/bin/env perl
2
3 use strict;
4 use warnings;
5
6 use Benchmark qw<cmpthese>;
7
8 use lib qw<blib/arch blib/lib>;
9 use Scalar::Vec::Util qw<vfill vcopy veq>;
10
11 BEGIN {
12  print 'We ';
13  if (eval "use Bit::Vector; 1") {
14   *HAS_BV = sub () { 1 };
15  } else {
16   *HAS_BV = sub () { 0 };
17   print "don't ";
18  }
19  print "have Bit::Vector.\n\n";
20 }
21
22 my $run = -1;
23 my $n   = 100_000;
24
25 sub inc {
26  ++$_[0];
27  $_[0] = 0 if $_[0] >= $n;
28  $_[0];
29 }
30
31 sub add {
32  $_[0] += $_[1];
33  $_[0] = 0 if $_[0] >= $n;
34  $_[0];
35 }
36
37 sub len {
38  return $n - ($_[0] > $_[1] ? $_[0] : $_[1])
39 }
40
41 sub bench_fill {
42  my ($tests, $desc) = @_;
43
44  my ($x, $y, $bv) = map "", 1 .. 2;
45  vec($_, $n - 1, 1) = 0 for $x, $y;
46  $bv = Bit::Vector->new($n, 1) if HAS_BV;
47
48  my ($i, $j, $k) = map 0, 1 .. 3;
49  my $m = @$tests;
50
51  print 'fill';
52  print ", $desc" if defined $desc;
53  print ":\n";
54
55  cmpthese $run, {
56   vfill     => sub {
57    my ($u, $v) = @{$tests->[$i]};
58    vfill($x, $u, $v, 1);
59    ++$i;
60    $i %= $m;
61   },
62   vfill_pp  => sub {
63    my ($u, $v) = @{$tests->[$j]};
64    Scalar::Vec::Util::vfill_pp($y, $u, $v, 1);
65    ++$j;
66    $j %= $m;
67   },
68   (vfill_bv => sub {
69    my ($u, $v) = @{$tests->[$k]};
70    $bv->Interval_Fill($u, $u + $v - 1);
71    ++$k;
72    $k %= $m;
73   }) x HAS_BV,
74  };
75
76  print "\n";
77 }
78
79 bench_fill [ map { my $i = $_; map [ $i, $n - $i - $_ ], 0 .. 8 } 0 .. 8 ];
80
81 sub bench_copy {
82  my ($tests, $desc) = @_;
83
84  my ($x1, $x2, $y1, $y2, $bv1, $bv2) = map "", 1 .. 4;
85  vec($_, $n - 1, 1) = 0 for $x1, $x2, $y1, $y2;
86  ($bv1, $bv2) = Bit::Vector->new($n, 2) if HAS_BV;
87
88  my ($i, $j, $k) = map 0, 1 .. 3;
89  my $m = @$tests;
90
91  print 'copy';
92  print ", $desc" if defined $desc;
93  print ":\n";
94
95  cmpthese $run, {
96   vcopy     => sub {
97    my ($u, $v, $w) = @{$tests->[$i]};
98    vcopy($x1, $u, $x2, $v, $w);
99    ++$i;
100    $i %= $m;
101   },
102   vcopy_pp  => sub {
103    my ($u, $v, $w) = @{$tests->[$j]};
104    Scalar::Vec::Util::vcopy_pp($y1, $u, $y2, $v, $w);
105    ++$j;
106    $j %= $m;
107   },
108   (vcopy_bv => sub {
109    my ($u, $v, $w) = @{$tests->[$k]};
110    $bv2->Interval_Copy($bv1, $v, $u, $w);
111    ++$k;
112    $k %= $m;
113   }) x HAS_BV,
114  };
115
116  print "\n";
117 }
118
119 bench_copy [
120  map {
121   my $i = $_;
122   map {
123    my $j = $i + 8 * $_;
124    map [ $i, $j, len($i, $j) - $_ ], 0 .. 8;
125   } 0 .. 8;
126  } 0 .. 8
127 ], 'aligned, forward';
128
129 bench_copy [
130  map {
131   my $i = $_;
132   map {
133    my $j = $i + 8 * $_;
134    map [ $j, $i, len($i, $j) - $_ ], 0 .. 8;
135   } 0 .. 8;
136  } 0 .. 8
137 ], 'aligned, backward';
138
139 bench_copy [
140  map {
141   my $i = $_;
142   map {
143    my $j = $_;
144    map [ $i, $j, len($i, $j) - $_ ], 0 .. 8;
145   } 0 .. 8;
146  } 0 .. 8
147 ], 'misaligned';
148
149 sub bench_move {
150  my ($tests, $desc) = @_;
151
152  my ($x, $y, $bv) = map "", 1 .. 2;
153  vec($_, $n - 1, 1) = 0 for $x, $y;
154  $bv = Bit::Vector->new($n, 1) if HAS_BV;
155
156  my ($i, $j, $k) = map 0, 1 .. 3;
157  my $m = @$tests;
158
159  print 'move';
160  print ", $desc" if defined $desc;
161  print ":\n";
162
163  cmpthese $run, {
164   vcopy     => sub {
165    my ($u, $v, $w) = @{$tests->[$i]};
166    vcopy($x, $u, $x, $v, $w);
167    ++$i;
168    $i %= $m;
169   },
170   vcopy_pp  => sub {
171    my ($u, $v, $w) = @{$tests->[$j]};
172    Scalar::Vec::Util::vcopy_pp($y, $u, $y, $v, $w);
173    ++$j;
174    $j %= $m;
175   },
176   (vcopy_bv => sub {
177    my ($u, $v, $w) = @{$tests->[$k]};
178    $bv->Interval_Copy($bv, $v, $u, $w);
179    ++$k;
180    $k %= $m;
181   }) x HAS_BV,
182  };
183
184  print "\n";
185 }
186
187 bench_move [
188  map {
189   my $i = $_;
190   map {
191    my $j = $i + 8 * $_;
192    map [ $i, $j, len($i, $j) - $_ ], 0 .. 8;
193   } 0 .. 8;
194  } 0 .. 8
195 ], 'aligned, forward';
196
197 bench_move [
198  map {
199   my $i = $_;
200   map {
201    my $j = $i + 8 * $_;
202    map [ $j, $i, len($i, $j) - $_ ], 0 .. 8;
203   } 0 .. 8;
204  } 0 .. 8
205 ], 'aligned, backward';
206
207 bench_move [
208  map {
209   my $i = $_;
210   map {
211    my $j = $_;
212    map [ $i, $j, len($i, $j) - $_ ], 0 .. 8;
213   } 0 .. 8;
214  } 0 .. 8
215 ], 'misaligned';
216
217 my $i = 0;
218 my $j = int $n / 2;
219 my $x = '';
220 vfill $x, 0, $n, 1;
221 my $y = '';
222 vfill $y, 0, $n, 1;
223 my ($bv1, $bv2, $bv3, $bv4);
224 if (HAS_BV) {
225  ($bv1, $bv2, $bv3, $bv4) = Bit::Vector->new($n, 4);
226  $bv1->Fill();
227  $bv2->Fill();
228 }
229
230 print "eq, origin:\n";
231 cmpthese $run, {
232  veq     => sub { veq $x, 0, $y, 0, $n },
233  veq_pp  => sub { Scalar::Vec::Util::veq_pp($x, 0, $y, 0, $n) },
234  (veq_bv => sub { $bv1->equal($bv2) }) x HAS_BV,
235 };
236 print "\n";
237
238 print "eq, random:\n";
239 cmpthese $run, {
240  veq     => sub { veq $x, inc($i), $y, inc($j), len($i, $j) },
241  veq_pp  => sub { Scalar::Vec::Util::veq_pp($x, inc($i), $y, inc($j), len($i, $j)) },
242  (veq_bv => sub {
243    inc($i);
244    inc($j);
245    my $l = len($i, $j);
246    $bv3->Resize($l);
247    $bv3->Interval_Copy($bv1, 0, $i, $l);
248    $bv4->Resize($l);
249    $bv4->Interval_Copy($bv2, 0, $j, $l);
250    $bv3->equal($bv4);
251   }) x HAS_BV,
252 };
253 print "\n";