use warnings; use strict; use Benchmark qw[ cmpthese ]; my @fields = ( { name => 'name1', start => 0, len=> 4 }, { name => 'name2', start => 3, len=> 7 }, { name => 'name3', start => 8, len=> 3 }, { name => 'name4', start => 0, len=> 10 }, { name => 'name5', start => 5, len=> 20 }, { name => 'name6', start => 11, len=> 14 }, { name => 'name7', start => 9, len=> 13 }, { name => 'name8', start => 2, len=> 2 }, { name => 'name9', start => 1, len=> 10 }, ); open FH, '<', $ARGV[ 0 ] or die $!; cmpthese -3, { 'unpack' => sub { my $unpack = ""; my $position = 0; for ( @fields ) { $unpack .= $_->{start} < $position ? 'X' . ( $position - $_->{start} ) : $_->{start} > $position ? 'x' . ( $_->{start} - $position ) : ''; $unpack .= 'A' . $_->{len}; $position = $_->{start}+$_->{len}; } seek FH, 0, 0; while( my $text = ) { my @a = unpack $unpack, $text; } }, 'substr' => sub { seek FH, 0, 0; while( my $text = ) { my @a = map{ substr $text, $_->{start}, $_->{len} } @fields; } } }; close FH; __END__ C:\test>for /l %i in (1,1,6) do holli data\alpha.1e%i C:\test>holli data\alpha.1e1 Rate unpack substr unpack 28603/s -- -80% substr 140302/s 391% -- C:\test>holli data\alpha.1e2 Rate substr unpack substr 400/s -- -26% unpack 540/s 35% -- C:\test>holli data\alpha.1e3 Rate substr unpack substr 40.3/s -- -27% unpack 54.9/s 36% -- C:\test>holli data\alpha.1e4 Rate substr unpack substr 4.06/s -- -28% unpack 5.61/s 38% -- C:\test>holli data\alpha.1e5 (warning: too few iterations for a reliable count) (warning: too few iterations for a reliable count) s/iter substr unpack substr 2.47 -- -27% unpack 1.80 37% -- C:\test>holli data\alpha.1e6 (warning: too few iterations for a reliable count) (warning: too few iterations for a reliable count) s/iter substr unpack substr 25.3 -- -29% unpack 18.0 40% --