I declare lanX the winner (with jmacnamara a close second) for a pure perl solution.
fletch's Inline C for absolute speed.
#! perl -slw use 5.010; use strict; use Inline C => Config => BUILD_NOISY => 1; use Inline C => <<'END_C', NAME => '_825494', CLEAN_AFTER_BUILD => 0; SV *interleave( SV *in, char other ) { size_t len = SvCUR( in ), i; SV *out = newSV( sizeof(char) * len * 2 ); char *outp = SvPVX( out ); char *p = SvPVX( in ); for( i = 0; i < len; ++i ) { *outp++ = *p++; *outp++ = other; } *outp = '\0'; SvPOK_on( out ); SvCUR_set( out, len * 2 ); return out; } END_C use Devel::Peek; use Benchmark qw[ cmpthese ]; use constant DEBUG => 0; ## Set to 1 to see first 20 bytes of results; our $in = chr(1) x 1e6; our $mask = ( chr( 0 ) . chr( 64 ) ) x 1e6; cmpthese DEBUG ? 1 : -3, { buk => q[ my $out = join( chr(64), unpack '(A1)*', $in ) . chr(64); print 'buk ', unpack 'C20', $out if DEBUG; ], shmem => q[ my $out = chr(64) x ( length( $in ) * 2 ); vec( $out, $_<<1, 8 ) = vec( $in, $_, 8 ) for 0..length( $in ) + -1; print 'shmem ', unpack 'C20', $out if DEBUG; ], salva => q[ my $out = chr(64) x ( length( $in ) * 2 ); substr( $out, $_ * 2, 1, substr( $in, $_, 1 ) ) for 0..length( + $in )-1; print 'salva ', unpack 'C20', $out if DEBUG; ], lanX => q[ my $out = pack 'S*', unpack 'C*', $in; $out |= $mask; print 'lanX ', unpack 'C20', $out if DEBUG;; ], jmac => q[ my $hi_bytes = pack 'v*', unpack 'C*', $in; my $lo_bytes = pack 'n*', ( 64 ) x length $in; my $out = $hi_bytes | $lo_bytes; print 'jmac ', unpack 'C20', $out if DEBUG;; ], fletch => q[ my $out = interleave( $in, chr( 64 ) ); print 'fletch', unpack 'C20', $out if DEBUG;; ], }; __END__ C:\test>825494 buk 164164164164164164164164164164 (warning: too few iterations for a reliable count) fletch164164164164164164164164164164 (warning: too few iterations for a reliable count) jmac 164164164164164164164164164164 (warning: too few iterations for a reliable count) lanX 164164164164164164164164164164 (warning: too few iterations for a reliable count) salva 164164164164164164164164164164 (warning: too few iterations for a reliable count) shmem 164164164164164164164164164164 (warning: too few iterations for a reliable count) C:\test>825494 Rate buk shmem salva jmac lanX fletch buk 2.10/s -- -26% -37% -76% -81% -99% shmem 2.84/s 36% -- -14% -68% -74% -99% salva 3.32/s 58% 17% -- -62% -69% -99% jmac 8.84/s 321% 211% 166% -- -18% -97% lanX 10.8/s 415% 279% 225% 22% -- -97% fletch 334/s 15849% 11662% 9968% 3685% 3000% --
In reply to Re: Interleaving bytes in a string quickly
by BrowserUk
in thread Interleaving bytes in a string quickly
by BrowserUk
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |