C:\test>1046579 -N=2**20 1048576 Rate single long classic str translate single 1.72/s -- -99% -100% -100% -100% long 134/s 7707% -- -71% -79% -81% classic 468/s 27047% 248% -- -26% -33% str 632/s 36579% 370% 35% -- -9% translate 695/s 40233% 417% 49% 10% -- C:\test>1046579 -N=2**30 1073741824 (warning: too few iterations for a reliable count) (warning: too few iterations for a reliable count) s/iter str translate str 1.96 -- -21% translate 1.54 27% -- #### #! perl -slw use strict; use Benchmark qw(cmpthese); sub single { ${ $_[0] } =~ s/(.)/~$1/ges; } sub long { ${ $_[0] } =~ s/(.{1,10000})/~$1/ges; } sub classic { ${ $_[0] } = ~${ $_[0] }; } sub str { my $blocksize = 10000; my $lb = length ${ $_[0] }; my $offset = 0; while( $offset < $lb ) { substr ${ $_[0] }, $offset, $blocksize, ~substr( ${ $_[0] }, $offset, $blocksize ); $offset += $blocksize; } } BEGIN { my $rev = join '', map sprintf( "\\x%02x", $_ ), reverse 0 .. 255; eval "sub translate { \${ \$_[0] } =~ tr[\\x00-\\xff][$rev] } ; 1 " or die $@; } our $N //= 256; $N = eval "0+$N"; #print $N; our $bits = pack 'C*', 0 .. 255; $bits x= ( $N / 256 ); cmpthese -3, { # classic => q[ classic( \$bits) ], # single => q[ single( \$bits ) ], # long => q[ long( \$bits ) ], translate => q[ translate( \$bits ) ], str => q[ str( \$bits ) ], };