← Index
NYTProf Performance Profile   « line view »
For v4.pl
  Run on Fri Sep 20 21:30:49 2019
Reported on Fri Sep 20 21:31:41 2019

Filename/homes/dcw/src/perl/weeklychallenge/perlweeklychallenge-club/challenge-025/duncan-c-white/perl5/v4.pl
StatementsExecuted 50686845 statements in 14.7s
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
50160782114.7s14.7smain::::findseq main::findseq (recurses: max depth 22, inclusive time 200s)
1111.28ms4.44msmain::::BEGIN@31 main::BEGIN@31
1111.18ms1.18msmain::::BEGIN@30 main::BEGIN@30
111263µs289µsmain::::BEGIN@29 main::BEGIN@29
1402126µs26µsmain::::CORE:match main::CORE:match (opcode)
11116µs16µsmain::::CORE:print main::CORE:print (opcode)
11111µs11µsmain::::BEGIN@28 main::BEGIN@28
1114µs4µsUNIVERSAL::::VERSIONUNIVERSAL::VERSION (xsub)
0000s0smain::::RUNTIME main::RUNTIME
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1#!/usr/bin/perl
2#
3# Challenge 1: "Generate a longest sequence of the following "English Pokemon"
4# names where each name starts with the last letter of the previous name:
5#
6# audino bagon baltoy banette bidoof braviary bronzor carracosta
7# charmeleon cresselia croagunk darmanitan deino emboar emolga
8# exeggcute gabite girafarig gulpin haxorus heatmor heatran ivysaur
9# jellicent jumpluff kangaskhan kricketune landorus ledyba loudred
10# lumineon lunatone machamp magnezone mamoswine nosepass petilil
11# pidgeotto pikachu pinsir poliwrath poochyena porygon2 porygonz
12# registeel relicanth remoraid rufflet sableye scolipede scrafty
13# seaking sealeo silcoon simisear snivy snorlax spoink starly
14# tirtouga trapinch treecko tyrogue vigoroth vulpix wailord
15# wartortle whismur wingull yamask"
16#
17# My notes: Clearly defined, nice, potentially tricky, let's do it.
18#
19# optimization v4: instead of extracting the last letter of each word,
20# precalculate %lw: word->last letter of word 14.8s
21# optimization v3: instead of cloning the used set to modify it,
22# modify it, pass it, and then change it back 21.1s
23# optimization v2: instead of recalculating the "used set" each time,
24# pass it around, modifying it as we go 28.8s
25# optimization v1: baseline code before starting to optimize: 32.6s.
26#
27
28231µs111µs
# spent 11µs within main::BEGIN@28 which was called: # once (11µs+0s) by main::NULL at line 28
use v5.10; # to get "say"
# spent 11µs making 1 call to main::BEGIN@28
292173µs2292µs
# spent 289µs (263+26) within main::BEGIN@29 which was called: # once (263µs+26µs) by main::NULL at line 29
use strict;
# spent 289µs making 1 call to main::BEGIN@29 # spent 2µs making 1 call to strict::import
3021.12ms21.19ms
# spent 1.18ms (1.18+6µs) within main::BEGIN@30 which was called: # once (1.18ms+6µs) by main::NULL at line 30
use warnings;
# spent 1.18ms making 1 call to main::BEGIN@30 # spent 4µs making 1 call to warnings::import
312214µs24.55ms
# spent 4.44ms (1.28+3.17) within main::BEGIN@31 which was called: # once (1.28ms+3.17ms) by main::NULL at line 31
use Function::Parameters;
# spent 4.44ms making 1 call to main::BEGIN@31 # spent 110µs making 1 call to Function::Parameters::import
32#use Data::Dumper;
33
341600nsmy $debug = @ARGV>0;
35
3613µsmy @words = qw(audino bagon baltoy banette bidoof braviary bronzor carracosta
37 charmeleon cresselia croagunk darmanitan deino emboar emolga
38 exeggcute gabite girafarig gulpin haxorus heatmor heatran ivysaur
39 jellicent jumpluff kangaskhan kricketune landorus ledyba loudred
40 lumineon lunatone machamp magnezone mamoswine nosepass petilil
41 pidgeotto pikachu pinsir poliwrath poochyena porygon2 porygonz
42 registeel relicanth remoraid rufflet sableye scolipede scrafty
43 seaking sealeo silcoon simisear snivy snorlax spoink starly
44 tirtouga trapinch treecko tyrogue vigoroth vulpix wailord
45 wartortle whismur wingull yamask);
46#@words = qw(hello ollie excellent thanks shelter runaround set to);
47
481100nsmy %sw; # hash from letter to list of words starting with that letter.
49
50my %lw; # mapping from word to last letter of word (precompute it:-))
51
521300nsforeach my $word (@words)
53{
547047µs7013µs $word =~ /^(.)/;
# spent 13µs making 70 calls to main::CORE:match, avg 186ns/call
55708µs my $letter = $1;
567031µs $sw{$letter} //= [];
577013µs push @{$sw{$letter}}, $word;
58
597047µs7013µs $word =~ /(.)$/;
# spent 13µs making 70 calls to main::CORE:match, avg 181ns/call
607031µs $lw{$word} = $1;
61}
62
63#die Dumper \%sw;
64#die Dumper \%lw;
65
661200nsmy @longseq = (); # longest sequence found so far..
67
68# search for sequences starting with each word in turn..
691200nsforeach my $sw (@words)
70{
7170125µs7014.7s findseq( $sw, {}, () );
# spent 14.7s making 70 calls to main::findseq, avg 210ms/call
72}
73
741200nsmy $longest = @longseq;
75
76123µs116µsprint "\nlongest sequence is length $longest: @longseq\n";
# spent 16µs making 1 call to main::CORE:print
771100nsexit 0;
78
79
80#
81# findseq( $currw, $used, @seq );
82# Find all sequences of words from $currw onwards,
83# given that we've already visited words in @seq,
84# (the same info, as a set, is in %$used)
85# and update the global @longseq if any sequences
86# we find are longer than that.
87#
88
# spent 14.7s within main::findseq which was called 5016078 times, avg 3µs/call: # 5016008 times (14.7s+-14.7s) by main::findseq at line 102, avg 0s/call # 70 times (236µs+14.7s) by main::RUNTIME at line 71, avg 210ms/call
fun findseq( $currw, $used, @seq )
89100321562.80s{
905016078440ms push @seq, $currw; # extend @seq sequence
91
925016078534ms $used->{$currw}++; # update $used set
93
945016078601ms my $lastletter = $lw{$currw}; # find the last letter of currw
95
965016078486ms my $nextw = $sw{$lastletter}; # all words starting with lastletter
975016078698ms if( defined $nextw ) # if there are any, try each word
98 {
99 foreach my $nextword (@$nextw)
100 {
101 findseq( $nextword, $used, @seq )
10278645142.64s50160080s unless $used->{$nextword};
# spent 200s making 5016008 calls to main::findseq, avg 40µs/call, recursion: max depth 22, sum of overlapping time 200s
103 }
104 } else # @seq is finished
105 {
106 #print "found sequence @seq\n";
107134658499.6ms my $len = @seq;
1081346584105ms if( $len > @longseq )
109 {
11016800ns print "longest seq so far (len $len): @seq\n" if $debug;
1111615µs @longseq = @seq;
112 }
113 }
11450160786.29s delete $used->{$currw};
115139µs14µs}
# spent 4µs making 1 call to Function::Parameters::_register_info
 
# spent 4µs within UNIVERSAL::VERSION which was called: # once (4µs+0s) by Function::Parameters::BEGIN@7 at line 24 of Scalar/Util.pm
sub UNIVERSAL::VERSION; # xsub
# spent 26µs within main::CORE:match which was called 140 times, avg 184ns/call: # 70 times (13µs+0s) by main::RUNTIME at line 54, avg 186ns/call # 70 times (13µs+0s) by main::RUNTIME at line 59, avg 181ns/call
sub main::CORE:match; # opcode
# spent 16µs within main::CORE:print which was called: # once (16µs+0s) by main::RUNTIME at line 76
sub main::CORE:print; # opcode