You should indeed use List::Util::max. However, just for the sake of variety, here is a compact way of getting the maximum of three arguments:
sub max_of_3 {
my $x = $_[ $_[1] > $_[0] ];
return $_[2] > $x ? $_[2] : $x;
}
Here is some test code along with benchmarks:
#!/usr/bin/env perl
use strict;
use warnings;
use Algorithm::Combinatorics qw( permutations );
use Dumbbench;
use List::Util qw( max );
use Test::More;
sub dummy { }
sub max_of_3 {
my $x = $_[ $_[1] > $_[0] ];
return $_[2] > $x ? $_[2] : $x;
}
sub classic {
my $num1 = $_[0];
my $num2 = $_[1];
my $num3 = $_[2];
my $max = $num1;
$max = $num2 if ($num2 > $max);
$max = $num3 if ($num3 > $max);
return $max;
}
for my $case ( permutations([5, 6, 7])) {
is max_of_3(@$case), 7, "max of [@$case] is 7";
}
done_testing;
my $bench = Dumbbench->new;
$bench->add_instances(
Dumbbench::Instance::PerlSub->new(
name => 'Dummy',
code => sub { dummy(5, 6, 7) },
),
Dumbbench::Instance::PerlSub->new(
name => 'compact',
code => sub { max_of_3(5, 6, 7) },
),
Dumbbench::Instance::PerlSub->new(
name => 'List::Util::max',
code => sub { max(5, 6, 7) },
),
Dumbbench::Instance::PerlSub->new(
name => 'classic',
code => sub { classic(5, 6, 7) },
),
);
$bench->run;
$bench->report;
Benchmark output:
Dummy: Ran 21 iterations (0 outliers).
Dummy: Rounded run time per iteration: 1.4729e-007 +/- 4.1e-010 (0.3%)
compact: Ran 27 iterations (7 outliers).
compact: Rounded run time per iteration: 3.8513e-007 +/- 8.4e-010 (0.2%)
List::Util::max: Ran 37 iterations (8 outliers).
List::Util::max: Rounded run time per iteration: 1.28262e-007 +/- 2.3e-011 (0.0%)
classic: Ran 27 iterations (7 outliers).
classic: Rounded run time per iteration: 5.81187e-007 +/- 9.2e-011 (0.0%)
The morals of the story: 1) Use well-established libraries instead of rolling your own. Here List::Util::max is faster than invoking a subroutine that does nothing because it is implemented in XS; 2) Prefer clarity over compactness unless you can come up with a really, really good reason. In most cases, even a 35% improvement in speed is not worth it, especially since using List::Util::max is simultaneously clearer, more compact and it performs better than both hand-rolled alternatives. You also don't have to write new code to handle N arguments.
List::Utilis core Perl and contains amax()function that does what yourmaximum()function is supposed to do. – DavidO Jan 2 at 18:40use strict;anduse warnings;to the top of every Perl file until you know exactly why each is recommended. – Brad Gilbert Jan 3 at 20:50