diff options
| author | drbaggy <js5@sanger.ac.uk> | 2021-04-21 00:56:59 +0100 |
|---|---|---|
| committer | drbaggy <js5@sanger.ac.uk> | 2021-04-21 00:56:59 +0100 |
| commit | cede56d142cf3553f6e96ecdbc7ba4ca142ca27f (patch) | |
| tree | cefa94e3b1cf569ddd7eb89466639baf2943f432 /challenge-109/james-smith | |
| parent | f89db52bf23d2277b9fc3c3007d20beb614e329c (diff) | |
| download | perlweeklychallenge-club-cede56d142cf3553f6e96ecdbc7ba4ca142ca27f.tar.gz perlweeklychallenge-club-cede56d142cf3553f6e96ecdbc7ba4ca142ca27f.tar.bz2 perlweeklychallenge-club-cede56d142cf3553f6e96ecdbc7ba4ca142ca27f.zip | |
push changes to chowla so that we can compare performances with Benchmark
Diffstat (limited to 'challenge-109/james-smith')
| -rw-r--r-- | challenge-109/james-smith/perl/ch-1.pl | 58 |
1 files changed, 51 insertions, 7 deletions
diff --git a/challenge-109/james-smith/perl/ch-1.pl b/challenge-109/james-smith/perl/ch-1.pl index 2c38afe0c4..1b89226a6a 100644 --- a/challenge-109/james-smith/perl/ch-1.pl +++ b/challenge-109/james-smith/perl/ch-1.pl @@ -5,18 +5,62 @@ use strict; use warnings; use feature qw(say); use Test::More; +use Benchmark qw(cmpthese); -my @answer = (9999, 0, 0, 0, 2, 0, 5, 0, 6, 3, 7, 0, 15, 0, 9, 8, 14, 0, 20, 0, 21); +my @answer = qw(9999 + 0 0 0 2 0 5 0 6 3 7 + 0 15 0 9 8 14 0 20 0 21 +); -is( chowla($_), $answer[ $_ ] ) foreach 1..20; +is( chowla_map($_), $answer[ $_ ] ) foreach 1..20; +is( chowla_for($_), $answer[ $_ ] ) foreach 1..20; done_testing(); -sub my_function { - sub chowla { - my ($t,$n) = (0,@_); - return ( map { (($n%$_) || ($t+=$_)) && () } 2..$n-1 ), $t; - } +## We will quickly run benchmarking... +## This suggests the for loop to be approximately 40-50% +## faster than the map solution... +## It is also 9 characters shorter... + +cmpthese(1_000_000, { + 'Map' => sub { chowla_map($_) foreach 1..20; }, + 'For' => sub { chowla_for($_) foreach 1..20; }, +}); + +## +## Rate Map For +## Map 38670/s -- -33% +## For 57670/s 49% -- +## + +sub chowla_map { + my ($t,$n) = (0,@_); +## First attempt - the one-liner is to write this as a map, +## we add $t at the end which is the value returned + ( map { (($n%$_) || ($t+=$_)) && () } 2..$n-1 ), $t; +} + +sub chowla_for { + my($t,$n)=(0,@_); + + ## This time we won't write this as a nasty map/reduce solution... + ## + ## Just a for loop; + ## + ## Notes: + ## * To allow for an "unless" in a postfix loop, we rewrite this + ## by noting: + ## unless( $condition ) { fun(); } + ## can be rewritten as: + ## ($condition)||($fun()) + ## * in perl `foreach` and `for` are synonymous - so we can shorten + + ($n%$_)||($t+=$_) for 2..$n-1; + + ## Now a quick "shortening" - if there is no specific return + ## statement - we can just omit the return in the last statement... + + $t; } |
