my %freq; for my $i ( 1 .. @data ) { $freq{ $1 }[ $-[0] ] += 1/@data while $data[ $i-1 ] =~ /(.)/g; } #### my $inc = 1 / @data; ## do the invariant once: for ( @data ) { ## $_ aliases each line in turn avoids both the $i-1 and indexing the array $freq{ $1 }[ $-[0] ] += $inc while /(.)/g; ## the regex engine operates directly on the $_ alias. } #### for( @data ) { ## use $_ to alias the lines my $p = -1; ## Allow pre-increment which is more efficient $freq{ chop() }[ ++$p ] += $inc while $_; ## implicit arg for chop; avoid call to length. }