note
Ven'Tatsu
I'm not sure how this fares in reguard to speed, but it only uses 2-5 scalars, tries to avoid generating intermidiate lists, and modifies their arguments inplace.
<code>
sub shrink {
my $dbit = 0;
for (my $sbit = 0; $sbit < length($_[0]) * 8; $sbit++) {
next if $sbit % 8 == 7;
vec($_[0], $dbit++, 1) = vec($_[0], $sbit, 1);
}
my $dlen = length($_[0]) * 7 / 8;
$dlen++ unless $dlen == int($dlen);
$dlen = int($dlen);
my $extra = length($_[0]) - $dlen;
if ($extra > 0) {
substr($_[0], $dlen, $extra, '');
}
for (my $pbit = $dbit; $pbit < $dlen * 8; $pbit++) {
vec($_[0], $pbit, 1) = 0;
}
}
sub grow {
my $sbit = int(length($_[0]) * 8 / 7) * 7 - 1;
for (my $dbit = int(length($_[0]) * 8 / 7) * 8 - 1; $dbit >= 0; $dbit--) {
vec($_[0], $dbit, 1) = $dbit % 8 == 7 ? 0 : vec($_[0], $sbit--, 1);
}
}
</code>
I have the nagging fealing there is a better way to implement <code>ceil</code> (near the middle of <code>shrink</code>).<br/>
If padding the compressed string with 0 bits is not needed then the second for loop of <code>shrink</code> can be omitted to save (on average) 4 bits of time.
439303
439321