1 package Scalar::Vec::Util;
10 Scalar::Vec::Util - Utility routines for vec strings.
23 XSLoader::load(__PACKAGE__, $VERSION);
26 *SVU_PP = sub () { 1 };
27 *SVU_SIZE = sub () { 1 };
36 use Scalar::Vec::Util qw/vfill vcopy veq/;
39 vfill $s, 0, 100, 1; # Fill with 100 bits 1 starting at 0.
41 vcopy $s, 20, $t, 10, 30; # Copy 30 bits from $s, starting at 20,
42 # to $t, starting at 10.
43 vcopy $t, 10, $t, 20, 30; # Overalapping areas DWIM.
44 if (veq $t, 10, $t, 20, 30) { ... } # Yes, they are equal now.
48 A set of utilities to manipulate bits in vec strings.
49 Highly optimized XS routines are used when available, but straightforward pure perl replacements are also provided for platforms without a C compiler.
51 This module doesn't reimplement bit vectors.
52 It can be used on the very same scalars that C<vec> builds, or actually on any Perl string (C<SVt_PV>).
58 True when pure perl fallbacks are used instead of XS functions.
62 Size in bits of the unit used for moves.
63 The higher this value is, the faster the XS functions are.
64 It's usually C<CHAR_BIT * $Config{alignbytes}>, except on non-little-endian architectures where it currently falls back to C<CHAR_BIT> (e.g. SPARC).
68 =head2 C<vfill $vec, $start, $length, $bit>
70 Starting at C<$start> in C<$vec>, fills C<$length> bits with C<$bit>.
71 Grows C<$vec> if necessary.
76 for (@_) { return 0 unless defined }
81 (undef, my $s, my $l, my $x) = @_;
82 croak "Invalid argument" unless _alldef @_;
85 vec($_[0], $_, 1) = $x for $s .. $s + $l - 1;
88 =head2 C<< vcopy $from => $from_start, $to => $to_start, $length >>
90 Copies C<$length> bits starting at C<$from_start> in C<$from> to C<$to_start> in C<$to>.
91 If C<$from_start + $length> is too long for C<$from>, zeros are copied past C<$length>.
92 Grows C<$to> if necessary.
93 Doesn't need to allocate any extra memory.
98 my ($fs, $ts, $l) = @_[1, 3, 4];
99 croak "Invalid argument" unless _alldef @_;
101 my $step = $ts - $fs;
103 vec($_[2], $_ + $step, 1) = vec($_[0], $_, 1) for $fs .. $fs + $l - 1;
104 } else { # There's a risk of overwriting if $_[0] and $_[2] are the same SV.
105 vec($_[2], $_ + $step, 1) = vec($_[0], $_, 1) for reverse $fs .. $fs + $l - 1;
109 =head2 C<< veq $v1 => $v1_start, $v2 => $v2_start, $length >>
111 Returns true if the C<$length> bits starting at C<$v1_start> in C<$v1> and C<$v2_start> in C<$v2> are equal, and false otherwise.
112 If needed, C<$length> is decreased to fit inside C<$v1> and C<$v2> boundaries.
117 my ($s1, $s2, $l) = @_[1, 3, 4];
118 croak "Invalid argument" unless _alldef @_;
121 return 0 if vec($_[0], $s1 + $i, 1) != vec($_[2], $s2 + $i, 1);
129 The functions L</vfill>, L</vcopy> and L</veq> are only exported on request.
130 All of them are exported by the tags C<':funcs'> and C<':all'>.
132 The constants L</SVU_PP> and L</SVU_SIZE> are also only exported on request.
133 They are all exported by the tags C<':consts'> and C<':all'>.
137 use base qw/Exporter/;
141 'funcs' => [ qw/vfill vcopy veq/ ],
142 'consts' => [ qw/SVU_PP SVU_SIZE/ ]
144 our @EXPORT_OK = map { @$_ } values %EXPORT_TAGS;
145 $EXPORT_TAGS{'all'} = [ @EXPORT_OK ];
149 The following timings were obtained by running the C<samples/bench.pl> script.
150 The C<_pp> entries are the pure Perl versions, whereas C<_bv> are L<Bit::Vector> versions.
154 =item This is for perl 5.8.8 on a Core 2 Duo 2.66GHz machine (unit is 64 bits).
156 Filling bits at a given position :
157 Rate vfill_pp vfill_bv vfill
158 vfill_pp 80.3/s -- -100% -100%
159 vfill_bv 1053399/s 1312401% -- -11%
160 vfill 1180792/s 1471129% 12% --
162 Copying bits from a bit vector to a different one :
163 Rate vcopy_pp vcopy_bv vcopy
164 vcopy_pp 112/s -- -100% -100%
165 vcopy_bv 62599/s 55622% -- -89%
166 vcopy 558491/s 497036% 792% --
168 Moving bits in the same bit vector from a given position to a different one :
169 Rate vmove_pp vmove_bv vmove
170 vmove_pp 64.8/s -- -100% -100%
171 vmove_bv 64742/s 99751% -- -88%
172 vmove 547980/s 845043% 746% --
174 Testing bit equality from different positions of different bit vectors :
175 Rate veq_pp veq_bv veq
176 veq_pp 92.7/s -- -100% -100%
177 veq_bv 32777/s 35241% -- -94%
178 veq 505828/s 545300% 1443% --
180 =item This is for perl 5.10.0 on a Pentium 4 3.0GHz (unit is 32 bits).
182 Rate vfill_pp vfill_bv vfill
183 vfill_pp 185/s -- -100% -100%
184 vfill_bv 407979/s 220068% -- -16%
185 vfill 486022/s 262184% 19% --
187 Rate vcopy_pp vcopy_bv vcopy
188 vcopy_pp 61.5/s -- -100% -100%
189 vcopy_bv 32548/s 52853% -- -83%
190 vcopy 187360/s 304724% 476% --
192 Rate vmove_pp vmove_bv vmove
193 vmove_pp 63.1/s -- -100% -100%
194 vmove_bv 32829/s 51933% -- -83%
195 vmove 188572/s 298787% 474% --
197 Rate veq_pp veq_bv veq
198 veq_pp 34.2/s -- -100% -100%
199 veq_bv 17518/s 51190% -- -91%
200 veq 192181/s 562591% 997% --
202 =item This is for perl 5.10.0 on an UltraSPARC-IIi (unit is 8 bits).
204 Rate vfill_pp vfill vfill_bv
205 vfill_pp 4.23/s -- -100% -100%
206 vfill 30039/s 709283% -- -17%
207 vfill_bv 36022/s 850568% 20% --
209 Rate vcopy_pp vcopy_bv vcopy
210 vcopy_pp 2.74/s -- -100% -100%
211 vcopy_bv 8146/s 297694% -- -60%
212 vcopy 20266/s 740740% 149% --
214 Rate vmove_pp vmove_bv vmove
215 vmove_pp 2.66/s -- -100% -100%
216 vmove_bv 8274/s 311196% -- -59%
217 vmove 20287/s 763190% 145% --
219 Rate veq_pp veq_bv veq
220 veq_pp 7.33/s -- -100% -100%
221 veq_bv 2499/s 33978% -- -87%
222 veq 19675/s 268193% 687% --
228 Please report architectures where we can't use the alignment as the move unit.
229 I'll add exceptions for them.
233 L<Carp>, L<Exporter> (core modules since perl 5), L<XSLoader> (since perl 5.006).
237 L<Bit::Vector> gives a complete reimplementation of bit vectors.
241 Vincent Pit, C<< <perl at profvince.com> >>, L<http://www.profvince.com>.
243 You can contact me by mail or on C<irc.perl.org> (vincent).
247 Please report any bugs or feature requests to C<bug-scalar-vec-util at rt.cpan.org>, or through the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Scalar-Vec-Util>.
248 I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
252 You can find documentation for this module with the perldoc command.
254 perldoc Scalar::Vec::Util
256 Tests code coverage report is available at L<http://www.profvince.com/perl/cover/Scalar-Vec-Util>.
258 =head1 COPYRIGHT & LICENSE
260 Copyright 2008 Vincent Pit, all rights reserved.
262 This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
266 1; # End of Scalar::Vec::Util