MimisIVI has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks,


My question is how can i read from a bit string one bit per time...
i fetch from the DBMS a binary compressed string and to
unpack the string i use the below code wich is extremely fast...
my $decode = unpack "b*",$compressed;

But because i need to read from the string a bit per time and the below code is very slow ...

my @bits = split(//, unpack("b*", $compressed));

i want to ask if there is a way to read from the compressed or the decode string a bit per time...



To compress the string i use this code:
my $compressed = pack "b*",$uncom;


Thanks for your Time..


Mimis

Replies are listed 'Best First'.
Re: Read Bit String...!!!
by ikegami (Patriarch) on Apr 09, 2008 at 14:04 UTC

    Things to try:

    • Leave the string compressed and use vec
    • Leave the string compressed and use masks (For example, $compressed & "\x80")
    • Replace split(//, unpack("b*", $compressed)) with my @bits = unpack("b*", $compressed) =~ /(.)/g
    • Skip assigning to an array using a regexp. (As in while ($decompressed =~ /(.)/g) { ... })
    • Skip assigning to an array using substr. (As in for my $i (0..length($decompressed)-1) { my $bit = substr($decompressed, $i, 1); ... })
    • ...

    If it's that slow, one has to wonder if you're using the optimal format for your data.

      And after all that if it's still slow and you're sure its the optimal format but you still want to stay in Perl consider dropping into C via Inline::C or an XS module and do the bit twiddling there instead.

      The cake is a lie.
      The cake is a lie.
      The cake is a lie.

        Dropping to C is indeed an option, but bit twiddling should be pretty darn fast in Perl too. To generate 1 million random numbers and process their bits took 4 seconds:

        my $stime = time; for (1..1_000_000) { my $i = rand(4294967295); while ($i) { $count++ if $i>>=2; } } my $etime = time; print($etime-$stime, " seconds to count the $count 1s in 32_000_000 bi +ts\n");
        4 seconds to count the 14665902 1s in 32_000_000 bits

        Update: Oops! if $i>>=2; should be if ($i>>=2) & 1; as per reply.

Re: Read Bit String...!!!
by stark (Pilgrim) on Apr 09, 2008 at 15:15 UTC

    Have you looked at Bit::Vector?

    With the Interval_xxx funtions it should be possible...

Re: Read Bit String...!!!
by MimisIVI (Acolyte) on Apr 09, 2008 at 15:12 UTC
    Hi guys,

    Ikegami i already use the three last solutions that you said
    and the regular expression is the best one...


    Now about the C solution the problem is that i dont know very well
    this language unfortunately and i dont have time to learn it..


    I believe if i will work the bit string without unpack it
    will be the fastest solution ..
    Can you give me some help with the mask and vec functions???

    About what i want to do with the bit string...

    In the string i save possitive compressed integers and to
    decode them i read from the start the string how many
    1s exist until i will find the first 0 (lets assume N ones).Then the compressed
    number is (in binary) the next N bits after the 0, plus an
    additional bit in the begining of the next N digits. Like this way for the next bits..


    For example lets assume that i compressed in the below bit string just one number...

    BitString: 1110,001
    N=3 (the first 1s until the first 0)
    The next N digits are : 001
    So the number in binary is 1001 by add one bit in the start of the next N bits...


    Can you tell me an optimal way to decode this bit string...??

    Thanks Guys!!!

    Mimis

      I believe if i will work the bit string without unpack it will be the fastest solution ..

      Why? I believe that you believe but why do you believe? I believe because either I have faith, or because I have read informed expert discussion, or because I have tested and know it to be true.

      For other monks information please refer to this to see what MimisIVI actually wants to do. I believe he is barking up the wrong tree, seeking the solution to a problem that does not actually exist, and trying to optimise a bad algorithm.