>perl -MO=Concise -e"\substr($_,1)" 2>&1 | find "substr" 5 <@> substr[t4] sKRM/2 ->6 ^ | "M"odifiable => magic created. >perl -MO=Concise -e"$a = substr($_,1)" 2>&1 | find "substr" 5 <@> substr[t3] sK/2 ->6 ^ | Not modifiable => no magic created. #### Pass 1: Creates a 79,999 char string & copies it into $a's buffer Pass 2: Creates a 79,998 char string & copies it into $a's buffer Pass 3: Creates a 79,997 char string & copies it into $a's buffer ... Pass 79,999: Creates a 1 char string & copies it into $a's buffer Pass 80,000: Creates a 0 char string & copies it into $a's buffer #### $a =~ s/.//s; # Remove leading char with no copying. substr($a, 0, 1, ''); # Remove leading char with no copying. #### -------------------- 20,000 Rate substr3 s/// substr4 substr3 1.61/s -- -93% -96% s/// 23.1/s 1336% -- -44% substr4 41.2/s 2460% 78% -- -------------------- 40,000 Rate substr3 s/// substr4 substr3 0.884/s -- -96% -98% s/// 23.1/s 2509% -- -45% substr4 41.6/s 4606% 80% -- -------------------- 80,000 Rate substr3 s/// substr4 substr3 0.445/s -- -98% -99% (warning: unreliable count) s/// 23.4/s 5162% -- -42% substr4 40.1/s 8897% 71% -- #### use strict; use warnings; use Benchmark qw( cmpthese ); my $OUTER = $ARGV[0] || -5; my %tests = ( 'substr3' => '$a = substr($a, 1)', 'substr4' => 'substr($a, 0, 1, "")', 's///' => '$a =~ s/.//s', ); my %bench = map { $_ => "use strict; use warnings; for (1 .. our $inner) { local our \$a = our \$arg; $tests{$_} while length(\$a); } " } keys %tests; for ( [ '20,000', 80_000/20_000, 'a' x 20_000 ], [ '40,000', 80_000/40_000, 'a' x 40_000 ], [ '80,000', 80_000/80_000, 'a' x 80_000 ], ) { my $name = $_->[0]; local our $inner = $_->[1] local our $arg = $_->[2]; print("--------------------\n"); print("$name\n"); print("\n"); cmpthese($OUTER, \%bench); print("\n"); }