http://qs1969.pair.com?node_id=952850

Limbic~Region has asked for the wisdom of the Perl Monks concerning the following question:

All,
I have millions of strings that are exactly 6 characters (bytes) long. Each position in the string can be one of 37 possible characters (space, 0-9 and A-Z). I need to very quickly compress these strings into the smallest space possible and also be able to expand them back again later as quickly as possible.

The implementation I have now uses 6 bits per character and compresses the string into 36 bits. I split the string in half (3 characters each) and use a hash look up to convert each half to a series of 1s and 0s. I concatenate the bitstrings together (with 4 bits of padding) and used pack('B*', $bitstr) to get from 6 bytes to 5.

I know that I can do better. 37 ^ 6 = 2_565_726_409 while 2 ^ 32 = 4_294_967_296. If I treated the string as a base 37 number, it would easily fit into a 32 bit integer (4 bytes). What I am at a loss for is how to quickly translate 0 into '      ' and 2_565_726_409 into 'ZZZZZZ';

My environment is perl 5.8.8 with no compiler so I am limited to pure perl modules only. What's the best that you can do?

Cheers - L~R