well, calling subs in Perl is not as expensive as people usually thing...
use Benchmark 'cmpthese';
my $a = 'foo bar doz' x 100;
$a .= ' hello '.$a;
my $sub = sub {
/\bhello\b/; /\bhello\b/; /\bhello\b/; /\bhello\b/;
/\bhello\b/; /\bhello\b/; /\bhello\b/; /\bhello\b/;
};
cmpthese(-3, { loop => sub {
for (($a) x 10) {
for my $i (1..8) {
/\bhello\b/;
}
}
},
sub => sub {
for (($a) x 10) {
$sub->()
}
},
inline => sub {
for (($a) x 10) {
/\bhello\b/; /\bhello\b/; /\bhello\b/; /\bhello\b/;
/\bhello\b/; /\bhello\b/; /\bhello\b/; /\bhello\b/;
}
}
outputs...
Rate loop sub inline
loop 4157/s -- -5% -16%
sub 4363/s 5% -- -12%
inline 4943/s 19% 13% --
and anyway, it's easy to modify my code to remove the subroutine call from the loop just moving the loop inside the sub:
open(MAP, "<$new_name_map_file");
while (<MAP>) {
chomp;
tr/A-Z/a-z/;
@map_line = split (/\t/);
$mapper{$map_line[0]} = $map_line[1];
}
close(MAP);
my $sub = <<'EOS';
sub {
while (<IN>) {
print "%";
tr/A-Z/a-z/;
EOS
for my $name (sort keys %mapper) {
my $qname = quotemeta $name;
my $qrepl = quotemeta $mapper{$name};
$sub .= "s{\b$qname\b}{$qrepl}g;\n";
}
$sub .= <<'EOS'
print OUT $_;
}
}
EOS
$sub = eval $sub;
die if $@;
open(IN, "<input_file");
open(OUT, ">input_file.new");
$sub->();
close(IN);
clse(OUT);
|