Just to test if it would bring speed (which I did not expect), I fiddled with pack and unpack. Before doing the hard part, I looked at the speeds halfway. It is not worth pursuing.
I also looked at Inline::C, and it is slower than your perl code (and I already optimized the stack stuff)
$ cat test.pl
use 5.016;
use warnings;
use Inline "C";
use Benchmark qw( cmpthese );
my $n = 0x80061861;
my $x = 10000;
sub andshift
{
my ($top14, $nxt6, $mid6, $bot6);
for (1 .. $x) {
$top14 = ($n & 0xfffc0000) >> 18;
$nxt6 = ($n & 0x0003f000) >> 12;
$mid6 = ($n & 0x00000fc0) >> 6;
$bot6 = ($n & 0x0000003f);
}
return ($top14, $nxt6, $mid6, $bot6);
} # andshift
sub packunpack
{
my ($top14, $nxt6, $mid6, $bot6);
for (1 .. $x) {
($top14, $nxt6, $mid6, $bot6) =
unpack "A14 A6 A6 A6", unpack "B32", => pack "N" => $n;
}
return ($top14, $nxt6, $mid6, $bot6);
} # packunpack
sub inlined
{
my ($top14, $nxt6, $mid6, $bot6);
for (1 .. $x) {
($top14, $nxt6, $mid6, $bot6) = split14666 ($n);
}
return ($top14, $nxt6, $mid6, $bot6);
} # inlined
say for andshift ();
say for packunpack ();
say for split14666 ($n);
cmpthese (-1, {
andshift => \&andshift,
bitstrings => \&packunpack,
inline_c => \&inlined,
});
__END__
__C__
void split14666 (int n)
{
Inline_Stack_Vars;
Inline_Stack_Reset;
EXTEND (sp, 4);
mPUSHi (((unsigned int)n & 0xfffc0000) >> 18);
mPUSHi (((unsigned int)n & 0x0003f000) >> 12);
mPUSHi (((unsigned int)n & 0x00000fc0) >> 6);
mPUSHi (((unsigned int)n & 0x0000003f) );
Inline_Stack_Done;
} /* split14666 */
$ perl test.pl
8193
33
33
33
10000000000001
100001
100001
100001
8193
33
33
33
Rate bitstrings inline_c andshift
bitstrings 121/s -- -52% -74%
inline_c 250/s 108% -- -47%
andshift 470/s 290% 88% --
Enjoy, Have FUN! H.Merijn
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.