The method is pretty much optimal but a little loop unrolling and speed/memory tradeoff can again speed it up a bit (a bit over twice as fast for fromB37() and a good 50% faster for toB37()). Using a couple 100K extra, it probably depends on the CPU's cache size though. Only changed/extra parts:
my @c3 = map { my $c = $_; (map { "$_$c" } @c1) } @c1;
sub myFromB37 {
my $n = shift;
my $s = ' ';
substr( $s, 0, 2, $c3[$n % 1369] );
$n /= 1369;
substr( $s, 2, 2, $c3[$n % 1369] );
$n /= 1369;
substr( $s, 4, 2, $c3[$n] );
$s;
}
my @c4;
$c4[unpack 'S', $c3[$_]] = $_ foreach 0 .. 1368;
sub myToB37 {
1874161 * $c4[unpack 'S', substr($_[0], 4, 2)] +
1369 * $c4[unpack 'S', substr($_[0], 2, 2)] +
$c4[unpack 'S', substr($_[0], 0, 2)];
}
my @num_data = map int( rand 37**6 ), 1 .. 1e6;
my @asc_data = map " $_", 'AAAAA' .. 'CEXHN';
The last lines pre-generate test data because my version depends on strings being no less then 6 characters; the rest of the benchmarking is analogous to yours. You could save one "reverse" in your version though by putting the characters in reverse order, which they should be anyway to represent a normal left-to-right base37 number.
-
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.