sub multi_add {
my $sum = 0;
$sum += $_ foreach @_;
return $sum;
}
my $result = multi_add(3,4,5);
####
{
my %dispatch = ();
sub arbitrary_operator_maker {
my $operation = shift;
my $num_elements = shift;
my $dispatch_key = "$operation$num_elements";
return $dispatch{$dispatch_key} if $dispatch{$dispatch_key};
my $built = join $operation, map {'$_[' . $_ . ']'} (0..$num_elements - 1);
return $dispatch{$dispatch_key} = eval "sub { $built }";
}
}
####
my $add_3_things = arbitrary_operator_maker('+', 3);
my $result = $add_3_things->(3,4,5);
print "$result\n";
my $other_result = $add_3_things->(77,88,99);
print "$other_result\n";
#etc.
####
my $add_3_things = arbitrary_operator_maker('+', 3);
$add_3_things internally looks like:
sub {
$_[0] + $_[1] + $_[2]
}
my $xor_5_things = arbitrary_operator_maker('^', 5);
$xor_5_things internally looks like:
sub {
$_[0] ^ $_[1] ^ $_[2] ^ $_[3] ^ $_[4]
}
####
my $op = '+';
my $and_maker_5 = arbitrary_operator_maker($op, 5);
my @list_5 = (1..5);
timethese(1000000, {
'and_maker 5 elements cached' => sub {
$and_maker_5->(@list_5);
},
'and_maker 5 elements dispatched' => sub {
my $and_maker_5 = arbitrary_operator_maker($op, 5);
$and_maker_5->(@list_5);
},
'multi_add 5 elements' => sub {
multi_add(@list_5);
},
});
Benchmark: timing 1000000 iterations of and_maker 5 elements cached, and_maker 5 elements dispatched, multi_add 5 elements...
and_maker 5 elements cached: 2 wallclock secs ( 0.98 usr + 0.00 sys = 0.98 CPU) @ 1020408.16/s (n=1000000)
and_maker 5 elements dispatched: 4 wallclock secs ( 2.95 usr + 0.01 sys = 2.96 CPU) @ 337837.84/s (n=1000000)
multi_add 5 elements: 3 wallclock secs ( 2.53 usr + 0.01 sys = 2.54 CPU) @ 393700.79/s (n=1000000)