in reply to Re: Interleaving bytes in a string quickly
in thread Interleaving bytes in a string quickly

The input string contains arbiitrary bytes (say, read from a file). $buf = chr(1) x 1e6 is simply a placeholder.


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
"I'd rather go naked than blow up my ass"

Replies are listed 'Best First'.
Re^3: Interleaving bytes in a string quickly
by shmem (Chancellor) on Feb 26, 2010 at 14:22 UTC

    Still vec can be used... differences are minimal:

    update: included jmcnamara's code, which is really fast.

    #!/usr/bin/perl use Benchmark qw(cmpthese); my $buf = chr(1) x 2e6; cmpthese(-10, { unpack => sub { # BrowserUk join( chr(0), unpack '(A1)*', $buf ) .chr(0) }, substr => sub { # salva $out = chr(0) x (length($buf) * 2); substr($out, $_ * 2, 1, substr($buf, $_, 1)) for 0..length +($buf); $out; }, vec => sub { # shmem $out = chr(0) x (length($buf) * 2); vec($out,$_<<1,8) = vec($buf,$_,8) for 0..length($buf)-1; $out; }, vec2 => sub { # jmcnamara my $out = pack 'v*', unpack 'C*', $buf; }, } ); __END__ s/iter vec unpack substr vec2 vec 1.44 -- -1% -3% -81% unpack 1.42 1% -- -2% -81% substr 1.40 3% 2% -- -80% vec2 0.275 423% 417% 408% --

    But your unpack routine doesn't seem to work correctly.

    update2: added jmcnamara's code to the stuff inside readmore tags

      But your unpack routine doesn't seem to work correctly.

      It does:

      $s = 'a' x 10; print join( 'B', unpack '(A1)*', $s ) . 'B';; aBaBaBaBaBaBaBaBaBaB

      But not with nulls. The template would have to be '(a1)*' in that case.


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.