FWIW, performing a quick benchmark indicates that using a hard-coded @comparisons (davidrw's initial suggestion) is significantly faster:
#!/usr/bin/perl -w
use strict;
use Benchmark qw(cmpthese);
my ($points, $quota) = (1000, 20);
cmpthese(
-1,
{
'op_orig' => sub { return op_orig($points, $quota);},
'op_cmp2' => sub { return op_cmp2($points, $quota);},
'davidrw_1' => sub { return davidrw_1($points, $quota);},
'davidrw_2' => sub { return davidrw_2($points, $quota);},
'ternary' => sub { return ternary_cmp($points, $quota);},
}
);
sub op_orig {
# OP, original compare
my ($points, $quota) = @_;
if ($points > 18000 && $quota < 24) {
return 24;
} elsif ($points > 16000 && $quota < 23) {
return 23;
} elsif ($points > 14000 && $quota < 22) {
return 22;
} elsif ($points > 12000 && $quota < 21) {
return 21;
} elsif ($points > 10000 && $quota < 20) {
return 20;
} elsif ($points > 8000 && $quota < 19) {
return 19;
} elsif ($points > 6000 && $quota < 18) {
return 18;
} elsif ($points > 4000 && $quota < 17) { #19
return 17;
} elsif ($points > 2000 && $quota < 16) { #17
return 16;
}
return 15;
}
sub op_cmp2 {
# OP, compare2
my ($points, $quota) = @_;
my $base_quota = 15;
while($points > 2000 && $quota > $base_quota) {
$points -= 2000;
$base_quota += 1;
}
return $base_quota;
}
sub davidrw_1 {
# davidrw suggestion 1
my ($points, $quota) = @_;
my @comparisons = (
# points, quota
[18000, 24],
[16000, 23],
[14000, 22],
[12000, 21],
[10000, 20],
[8000, 19],
[6000, 18],
[4000, 17],
[2000, 16],
);
foreach my $cmp (@comparisons) {
return $cmp->[1] if $points > $cmp->[0] && $quota < $cmp->[1];
}
return 15;
}
sub davidrw_2 {
# davidrw suggestion 2
my ($points, $quota) = @_;
my @comparisons = map { [($_ - 15) * 2000, $_] } 24 .. 16;
foreach my $cmp (@comparisons) {
return $cmp->[1] if $points > $cmp->[0] && $quota < $cmp->[1];
}
return 15;
}
sub ternary_cmp {
# Just for the fun of it
my ($points, $quota) = @_;
return ($points > 18000 && $quota < 24) ? 24
: ($points > 16000 && $quota < 23) ? 23
: ($points > 14000 && $quota < 22) ? 22
: ($points > 12000 && $quota < 21) ? 21
: ($points > 10000 && $quota < 20) ? 20
: ($points > 8000 && $quota < 19) ? 19
: ($points > 6000 && $quota < 18) ? 18
: ($points > 4000 && $quota < 17) ? 17
: ($points > 2000 && $quota < 16) ? 16
: 15;
}
__END__
Rate davidrw_1 op_orig ternary davidrw_2 op_cmp2
davidrw_1 22411/s -- -86% -86% -87% -90%
op_orig 162293/s 624% -- -1% -4% -29%
ternary 163840/s 631% 1% -- -3% -28%
davidrw_2 169239/s 655% 4% 3% -- -26%
op_cmp2 227555/s 915% 40% 39% 34% --
Update: Added kutsu's suggestion to the mix:
Rate kutsu davidrw_1 op_orig ternary davidrw_2 op_cmp2
kutsu 15170/s -- -31% -90% -91% -91% -93%
davidrw_1 21976/s 45% -- -86% -86% -87% -90%
op_orig 159288/s 950% 625% -- -1% -9% -31%
ternary 160777/s 960% 632% 1% -- -8% -30%
davidrw_2 174121/s 1048% 692% 9% 8% -- -24%
op_cmp2 229681/s 1414% 945% 44% 43% 32% --
|