in reply to Interleaving bytes in a string quickly

Hi

It's a repeated task for many buf-strings of fixed length to convert?

If yes, you may wanna try to pack(unpack $string) such that each byte is transformed to the highbyte of a 16-bit word and the lowbyte is 0.

Then just "or" with constant string with the "fixed byte" at lowbyte positions (that are 1,3,5..., the odd indexes).

Should be faster since you avoid looping bytewise on the perl level... but I have no time to try it out now.

Cheers Rolf

Update: corrected

Replies are listed 'Best First'.
Re^2: Interleaving bytes in a string quickly
by LanX (Saint) on Feb 26, 2010 at 15:03 UTC
    roughly 5-7 times faster!

    $mult=1e7; $buf = chr(1) x $mult; $s = time; $out = join( chr(0), unpack '(A1)*', $buf ) .chr(0); print "TIME0:",time() - $s,"\n"; $del=pack('(B16)*','00000000'.'11111111')x $mult; $buf="ABCDEFGHIJ"x($mult/10); $s = time(); #$buf2=pack('(B16)*',unpack('(B8)*',$buf)); $buf2=pack 'v*', unpack 'C*', $buf; # jmcnamaras pack-unpac +k-ing is much faster !!! $out = $del|$buf2; print "TIME1:",time() - $s,"\n"; print join ",",unpack '(B8)20',$out; # check result
    OUT:

    TIME0:14 TIME1:2 01000001,11111111,01000010,11111111,01000011,11111111,01000100,1111111 +1,01000101,11111111,01000110,11111111,01000111,11111111,01001000,1111 +1111,01001001,11111111,01001010,11111111

    Cheers Rolf

    UPDATE: even if it's a one-time task you can profit from this approach by chunking the string into eqally sized pieces which are "or"ed against the precalculated $del string.

    UPDATE: even if you include calculating $del it's about 3 times faster!