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.
qwurx [shmem] ~> wc -c interleave.pl 715 qwurx [shmem] ~> perl interleave.pl vec: 1430 #!/usr/bin/perl #my $buf = chr(1) x 2e6; my $buf = do { local $/; seek DATA,0,0; <DATA> }; my $c = { unpack => sub { join( chr(0), unpack '(A1)*', $buf ) .chr(0) }, substr => sub { my $out = chr(0) x (length($buf) * 2); substr($out, $_ * 2, 1, substr($buf, $_, 1)) for 0..length($bu +f); $out; }, vec => sub { my $out = chr(0) x (length($buf) * 2); vec($out,$_<<1,8) = vec($buf,$_,8) for 0..length($buf)-1; $out; }, vec2 => sub { my $out = pack 'v*', unpack 'C*', $buf; } }; for (keys %$c) { my $out = $c->{$_}->(); (my $c = $out) =~ s/\0//g; print "$_: ",length($out),$/,$c,$/; } __DATA__ vec2: 1430 #!/usr/bin/perl #my $buf = chr(1) x 2e6; my $buf = do { local $/; seek DATA,0,0; <DATA> }; my $c = { unpack => sub { join( chr(0), unpack '(A1)*', $buf ) .chr(0) }, substr => sub { my $out = chr(0) x (length($buf) * 2); substr($out, $_ * 2, 1, substr($buf, $_, 1)) for 0..length($bu +f); $out; }, vec => sub { my $out = chr(0) x (length($buf) * 2); vec($out,$_<<1,8) = vec($buf,$_,8) for 0..length($buf)-1; $out; }, vec2 => sub { my $out = pack 'v*', unpack 'C*', $buf; } }; for (keys %$c) { my $out = $c->{$_}->(); (my $c = $out) =~ s/\0//g; print "$_: ",length($out),$/,$c,$/; } __DATA__ substr: 1430 #!/usr/bin/perl #my $buf = chr(1) x 2e6; my $buf = do { local $/; seek DATA,0,0; <DATA> }; my $c = { unpack => sub { join( chr(0), unpack '(A1)*', $buf ) .chr(0) }, substr => sub { my $out = chr(0) x (length($buf) * 2); substr($out, $_ * 2, 1, substr($buf, $_, 1)) for 0..length($bu +f); $out; }, vec => sub { my $out = chr(0) x (length($buf) * 2); vec($out,$_<<1,8) = vec($buf,$_,8) for 0..length($buf)-1; $out; }, vec2 => sub { my $out = pack 'v*', unpack 'C*', $buf; } }; for (keys %$c) { my $out = $c->{$_}->(); (my $c = $out) =~ s/\0//g; print "$_: ",length($out),$/,$c,$/; } __DATA__ unpack: 1193 #!/usr/bin/perl#my$buf=chr(1)x2e6;my$buf=do{local$/;seekDATA,0,0;<DATA +>};my$c={unpack=>sub{join(chr(0),unpack'(A1)*',$buf).chr(0)},substr=> +sub{my$out=chr(0)x(length($buf)*2);substr($out,$_*2,1,substr($buf,$_, +1))for0..length($buf);$out;},vec=>sub{my$out=chr(0)x(length($buf)*2); +vec($out,$_<<1,8)=vec($buf,$_,8)for0..length($buf)-1;$out;},vec2=>sub +{my$out=pack'v*',unpack'C*',$buf;}};for(keys%$c){my$out=$c->{$_}->(); +(my$c=$out)=~s/\0//g;print"$_:",length($out),$/,$c,$/;}__DATA__
update2: added jmcnamara's code to the stuff inside readmore tags
In reply to Re^3: Interleaving bytes in a string quickly
by shmem
in thread Interleaving bytes in a string quickly
by BrowserUk
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |