Filename | /usr/local/share/perl/5.18.2/String/Markov.pm |
Statements | Executed 57171 statements in 95.4ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
386 | 1 | 1 | 32.3ms | 42.8ms | add_sample | String::Markov::
2703 | 1 | 1 | 27.1ms | 28.7ms | split_prob | String::Markov::
2 | 1 | 1 | 20.8ms | 49.5ms | split_all_prob | String::Markov::
386 | 1 | 1 | 3.96ms | 10.5ms | split_line | String::Markov::
1 | 1 | 1 | 3.36ms | 4.50ms | BEGIN@11 | String::Markov::
2 | 2 | 1 | 2.91ms | 96.9ms | add_files | String::Markov::
1 | 1 | 1 | 2.38ms | 20.2ms | BEGIN@8 | String::Markov::
136 | 1 | 1 | 1.71ms | 1.71ms | sample_next_state | String::Markov::
388 | 1 | 1 | 1.65ms | 1.65ms | CORE:readline (opcode) | String::Markov::
2703 | 1 | 1 | 1.58ms | 1.58ms | CORE:sort (opcode) | String::Markov::
1 | 1 | 1 | 1.15ms | 14.9ms | BEGIN@9 | String::Markov::
7 | 2 | 1 | 635µs | 2.35ms | generate_sample | String::Markov::
386 | 1 | 1 | 301µs | 301µs | CORE:regcomp (opcode) | String::Markov::
2 | 1 | 1 | 44µs | 60µs | __ANON__[:45] | String::Markov::
1 | 1 | 1 | 33µs | 33µs | BEGIN@7 | String::Markov::
2 | 1 | 1 | 16µs | 23µs | __ANON__[:20] | String::Markov::
1 | 1 | 1 | 16µs | 91µs | BEGIN@12 | String::Markov::
2 | 1 | 1 | 14µs | 14µs | __ANON__[:14] | String::Markov::
1 | 1 | 1 | 12µs | 12µs | do_chomp (xsub) | String::Markov::
4 | 2 | 1 | 7µs | 7µs | __ANON__[:29] | String::Markov::
2 | 1 | 1 | 7µs | 7µs | CORE:match (opcode) | String::Markov::
4 | 2 | 1 | 6µs | 6µs | __ANON__[:30] | String::Markov::
2 | 1 | 1 | 5µs | 5µs | __ANON__[:15] | String::Markov::
2 | 1 | 1 | 5µs | 5µs | __ANON__[:16] | String::Markov::
4 | 4 | 1 | 3µs | 3µs | join_sep (xsub) | String::Markov::
2 | 1 | 1 | 3µs | 3µs | __ANON__[:17] | String::Markov::
2 | 2 | 1 | 3µs | 3µs | null (xsub) | String::Markov::
3 | 3 | 1 | 3µs | 3µs | order (xsub) | String::Markov::
3 | 3 | 1 | 3µs | 3µs | transition_count (xsub) | String::Markov::
2 | 2 | 1 | 2µs | 2µs | split_sep (xsub) | String::Markov::
2 | 2 | 1 | 2µs | 2µs | row_sum (xsub) | String::Markov::
1 | 1 | 1 | 1µs | 1µs | stable (xsub) | String::Markov::
1 | 1 | 1 | 700ns | 700ns | normalize (xsub) | String::Markov::
0 | 0 | 0 | 0s | 0s | __ANON__[:24] | String::Markov::
0 | 0 | 0 | 0s | 0s | join_prob | String::Markov::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | package String::Markov; | ||||
2 | |||||
3 | # ABSTRACT: A Moo-based, text-oriented Markov Chain module | ||||
4 | |||||
5 | 1 | 500ns | our $VERSION = 0.009; | ||
6 | |||||
7 | 2 | 78µs | 1 | 33µs | # spent 33µs within String::Markov::BEGIN@7 which was called:
# once (33µs+0s) by main::BEGIN@7 at line 7 # spent 33µs making 1 call to String::Markov::BEGIN@7 |
8 | 2 | 115µs | 2 | 21.3ms | # spent 20.2ms (2.38+17.9) within String::Markov::BEGIN@8 which was called:
# once (2.38ms+17.9ms) by main::BEGIN@7 at line 8 # spent 20.2ms making 1 call to String::Markov::BEGIN@8
# spent 1.08ms making 1 call to Moo::import |
9 | 2 | 118µs | 2 | 15.0ms | # spent 14.9ms (1.15+13.8) within String::Markov::BEGIN@9 which was called:
# once (1.15ms+13.8ms) by main::BEGIN@7 at line 9 # spent 14.9ms making 1 call to String::Markov::BEGIN@9
# spent 38µs making 1 call to namespace::autoclean::import |
10 | |||||
11 | 2 | 196µs | 2 | 4.68ms | # spent 4.50ms (3.36+1.14) within String::Markov::BEGIN@11 which was called:
# once (3.36ms+1.14ms) by main::BEGIN@7 at line 11 # spent 4.50ms making 1 call to String::Markov::BEGIN@11
# spent 185µs making 1 call to Exporter::import |
12 | 2 | 1.94ms | 2 | 135µs | # spent 91µs (16+75) within String::Markov::BEGIN@12 which was called:
# once (16µs+75µs) by main::BEGIN@7 at line 12 # spent 91µs making 1 call to String::Markov::BEGIN@12
# spent 44µs making 1 call to List::Util::import |
13 | |||||
14 | 3 | 21µs | 1 | 22.5ms | # spent 14µs within String::Markov::__ANON__[/usr/local/share/perl/5.18.2/String/Markov.pm:14] which was called 2 times, avg 7µs/call:
# 2 times (14µs+0s) by String::Markov::new at line 111 of (eval 33)[Sub/Quote.pm:3], avg 7µs/call # spent 22.5ms making 1 call to Moo::has |
15 | 3 | 13µs | 1 | 208µs | # spent 5µs within String::Markov::__ANON__[/usr/local/share/perl/5.18.2/String/Markov.pm:15] which was called 2 times, avg 3µs/call:
# 2 times (5µs+0s) by String::Markov::new at line 111 of (eval 33)[Sub/Quote.pm:3], avg 3µs/call # spent 208µs making 1 call to Moo::has |
16 | 3 | 11µs | 1 | 230µs | # spent 5µs within String::Markov::__ANON__[/usr/local/share/perl/5.18.2/String/Markov.pm:16] which was called 2 times, avg 2µs/call:
# 2 times (5µs+0s) by String::Markov::new at line 111 of (eval 33)[Sub/Quote.pm:3], avg 2µs/call # spent 230µs making 1 call to Moo::has |
17 | 3 | 12µs | 1 | 208µs | # spent 3µs within String::Markov::__ANON__[/usr/local/share/perl/5.18.2/String/Markov.pm:17] which was called 2 times, avg 2µs/call:
# 2 times (3µs+0s) by String::Markov::new at line 111 of (eval 33)[Sub/Quote.pm:3], avg 2µs/call # spent 208µs making 1 call to Moo::has |
18 | has order => (is => 'ro', isa => sub { | ||||
19 | 2 | 25µs | 2 | 7µs | die "Need an integer greater than zero" if !$_[0] || $_[0] =~ /\D/; # spent 7µs making 2 calls to String::Markov::CORE:match, avg 4µs/call |
20 | 1 | 6µs | 1 | 209µs | # spent 23µs (16+7) within String::Markov::__ANON__[/usr/local/share/perl/5.18.2/String/Markov.pm:20] which was called 2 times, avg 12µs/call:
# 2 times (16µs+7µs) by String::Markov::new at line 71 of (eval 33)[Sub/Quote.pm:3], avg 12µs/call # spent 209µs making 1 call to Moo::has |
21 | |||||
22 | has ['split_sep','join_sep'] => ( | ||||
23 | is => 'rw', | ||||
24 | default => sub { undef } | ||||
25 | 1 | 10µs | 1 | 384µs | ); # spent 384µs making 1 call to Moo::has |
26 | |||||
27 | has ['transition_count','row_sum'] => ( | ||||
28 | is => 'ro', | ||||
29 | 4 | 13µs | # spent 7µs within String::Markov::__ANON__[/usr/local/share/perl/5.18.2/String/Markov.pm:29] which was called 4 times, avg 2µs/call:
# 2 times (5µs+0s) by String::Markov::new at line 94 of (eval 33)[Sub/Quote.pm:3], avg 3µs/call
# 2 times (2µs+0s) by String::Markov::new at line 123 of (eval 33)[Sub/Quote.pm:3], avg 1µs/call | ||
30 | 4 | 12µs | # spent 6µs within String::Markov::__ANON__[/usr/local/share/perl/5.18.2/String/Markov.pm:30] which was called 4 times, avg 1µs/call:
# 2 times (4µs+0s) by String::Markov::new at line 82 of (eval 33)[Sub/Quote.pm:3], avg 2µs/call
# 2 times (2µs+0s) by String::Markov::new at line 111 of (eval 33)[Sub/Quote.pm:3], avg 1µs/call | ||
31 | 1 | 7µs | 1 | 425µs | ); # spent 425µs making 1 call to Moo::has |
32 | |||||
33 | # spent 60µs (44+15) within String::Markov::__ANON__[/usr/local/share/perl/5.18.2/String/Markov.pm:45] which was called 2 times, avg 30µs/call:
# 2 times (44µs+15µs) by String::Markov::__ANON__[(eval 16)[/usr/local/share/perl/5.18.2/Class/Method/Modifiers.pm:93]:1] at line 1 of (eval 16)[Class/Method/Modifiers.pm:93], avg 30µs/call | ||||
34 | 2 | 5µs | my ($orig, $class, @arg) = @_; | ||
35 | 2 | 1µs | my %ahash; | ||
36 | |||||
37 | 2 | 7µs | %ahash = @arg == 1 ? %{$arg[0]} : @arg; | ||
38 | |||||
39 | 2 | 4µs | my $sep = delete $ahash{sep} // ''; | ||
40 | 2 | 1µs | die "ERR: sep argument must be scalar; did you mean to set split_sep instead?" if ref $sep; | ||
41 | 2 | 3µs | $ahash{split_sep} //= $sep; | ||
42 | 2 | 2µs | $ahash{join_sep} //= $sep; | ||
43 | |||||
44 | 2 | 16µs | 2 | 16µs | return $class->$orig(\%ahash); # spent 16µs making 2 calls to Moo::Object::BUILDARGS, avg 8µs/call |
45 | 1 | 6µs | 1 | 2.17ms | }; # spent 2.17ms making 1 call to Moo::around |
46 | |||||
47 | sub join_prob { | ||||
48 | my ($self, $orig_prob) = @_; | ||||
49 | my %p; | ||||
50 | |||||
51 | @p{@{$orig_prob->[0]}} = @{$orig_prob->[1]}; | ||||
52 | |||||
53 | return \%p; | ||||
54 | } | ||||
55 | |||||
56 | # spent 28.7ms (27.1+1.58) within String::Markov::split_prob which was called 2703 times, avg 11µs/call:
# 2703 times (27.1ms+1.58ms) by String::Markov::split_all_prob at line 78, avg 11µs/call | ||||
57 | 2703 | 794µs | my ($self, $orig_prob) = @_; | ||
58 | |||||
59 | 2703 | 1.13ms | 1 | 1µs | if ($self->stable) { # spent 1µs making 1 call to String::Markov::stable |
60 | 2703 | 18.7ms | 2703 | 1.58ms | my @k = sort keys %$orig_prob; # spent 1.58ms making 2703 calls to String::Markov::CORE:sort, avg 585ns/call |
61 | return [ | ||||
62 | \@k, | ||||
63 | 2703 | 17.0ms | [@{$orig_prob}{@k}], | ||
64 | ]; | ||||
65 | } else { | ||||
66 | return [ | ||||
67 | [keys %$orig_prob], | ||||
68 | [values %$orig_prob], | ||||
69 | ]; | ||||
70 | } | ||||
71 | } | ||||
72 | |||||
73 | # spent 49.5ms (20.8+28.7) within String::Markov::split_all_prob which was called 2 times, avg 24.7ms/call:
# 2 times (20.8ms+28.7ms) by String::Markov::add_files at line 139, avg 24.7ms/call | ||||
74 | 2 | 2µs | my $self = shift; | ||
75 | 2 | 8µs | 1 | 1µs | my $tc = $self->transition_count; # spent 1µs making 1 call to String::Markov::transition_count |
76 | 2 | 2µs | my $nt = {}; | ||
77 | |||||
78 | 2 | 8.33ms | 2703 | 28.7ms | while (my ($state, $prob) = each %$tc) { # spent 28.7ms making 2703 calls to String::Markov::split_prob, avg 11µs/call |
79 | $nt->{$state} = $self->split_prob($prob); | ||||
80 | } | ||||
81 | |||||
82 | 2 | 3.56ms | %$tc = %$nt; | ||
83 | } | ||||
84 | |||||
85 | # spent 10.5ms (3.96+6.57) within String::Markov::split_line which was called 386 times, avg 27µs/call:
# 386 times (3.96ms+6.57ms) by String::Markov::add_sample at line 105, avg 27µs/call | ||||
86 | 386 | 211µs | my ($self, $sample) = @_; | ||
87 | 386 | 823µs | 387 | 6.27ms | if (my $norm = $self->normalize) { # spent 6.27ms making 386 calls to Unicode::Normalize::normalize, avg 16µs/call
# spent 700ns making 1 call to String::Markov::normalize |
88 | $sample = normalize($norm, $sample); | ||||
89 | } | ||||
90 | 386 | 3.42ms | 387 | 302µs | return split($self->split_sep, $sample); # spent 301µs making 386 calls to String::Markov::CORE:regcomp, avg 779ns/call
# spent 900ns making 1 call to String::Markov::split_sep |
91 | } | ||||
92 | |||||
93 | # spent 42.8ms (32.3+10.5) within String::Markov::add_sample which was called 386 times, avg 111µs/call:
# 386 times (32.3ms+10.5ms) by String::Markov::add_files at line 136, avg 111µs/call | ||||
94 | 386 | 237µs | my ($self, $sample) = @_; | ||
95 | 386 | 292µs | 1 | 1µs | my $n = $self->order; # spent 1µs making 1 call to String::Markov::order |
96 | 386 | 194µs | 1 | 700ns | my $null = $self->null; # spent 700ns making 1 call to String::Markov::null |
97 | |||||
98 | 386 | 130µs | my $sref = ref $sample; | ||
99 | 386 | 347µs | my @nms = ($null,) x $n; | ||
100 | |||||
101 | 386 | 423µs | if ($sref eq 'ARRAY') { | ||
102 | push @nms, @$sample; | ||||
103 | } elsif (!$sref) { | ||||
104 | 386 | 219µs | 1 | 1µs | die 'ERR: missing split separator,' if !defined $self->split_sep; # spent 1µs making 1 call to String::Markov::split_sep |
105 | 386 | 1.06ms | 386 | 10.5ms | push @nms, $self->split_line($sample); # spent 10.5ms making 386 calls to String::Markov::split_line, avg 27µs/call |
106 | } else { | ||||
107 | die "ERR: bad sample type $sref"; | ||||
108 | } | ||||
109 | |||||
110 | 386 | 225µs | push @nms, $null; | ||
111 | |||||
112 | 386 | 281µs | 1 | 1µs | my $sep = $self->join_sep // ''; # spent 1µs making 1 call to String::Markov::join_sep |
113 | 386 | 180µs | 1 | 800ns | my $count = $self->transition_count; # spent 800ns making 1 call to String::Markov::transition_count |
114 | 386 | 166µs | 1 | 900ns | my $sum = $self->row_sum; # spent 900ns making 1 call to String::Markov::row_sum |
115 | 386 | 642µs | for my $i (0 .. ($#nms - $n)) { | ||
116 | 6142 | 5.87ms | my $cur = join($sep, @nms[$i .. ($i + $n - 1)]); | ||
117 | 6142 | 2.20ms | my $nxt = $nms[$i + $n]; | ||
118 | 6142 | 3.28ms | my $prob = $count->{$cur}; | ||
119 | 6142 | 1.92ms | if ($prob && ref $prob ne 'HASH') { | ||
120 | $count->{$cur} = $self->join_prob($prob); | ||||
121 | } | ||||
122 | 6142 | 7.78ms | ++$count->{$cur}{$nxt}; | ||
123 | 6142 | 5.38ms | ++$sum->{$cur}; | ||
124 | } | ||||
125 | |||||
126 | 386 | 1.65ms | return $self; | ||
127 | } | ||||
128 | |||||
129 | # spent 96.9ms (2.91+94.0) within String::Markov::add_files which was called 2 times, avg 48.4ms/call:
# once (1.96ms+51.3ms) by main::RUNTIME at line 18 of index.cgi
# once (950µs+42.6ms) by main::RUNTIME at line 43 of index.cgi | ||||
130 | 2 | 3µs | my ($self, @files) = @_; | ||
131 | 2 | 20µs | 1 | 12µs | my $do_chomp = $self->do_chomp; # spent 12µs making 1 call to String::Markov::do_chomp |
132 | |||||
133 | 2 | 4µs | local @ARGV = @files; | ||
134 | 2 | 2.66ms | 388 | 1.65ms | while(my $sample = <>) { # spent 1.65ms making 388 calls to String::Markov::CORE:readline, avg 4µs/call |
135 | 386 | 186µs | chomp $sample if $do_chomp; | ||
136 | 386 | 750µs | 386 | 42.8ms | $self->add_sample($sample); # spent 42.8ms making 386 calls to String::Markov::add_sample, avg 111µs/call |
137 | } | ||||
138 | |||||
139 | 2 | 283µs | 2 | 49.5ms | $self->split_all_prob(); # spent 49.5ms making 2 calls to String::Markov::split_all_prob, avg 24.7ms/call |
140 | |||||
141 | 2 | 19µs | return $self; | ||
142 | } | ||||
143 | |||||
144 | # spent 1.71ms (1.71+3µs) within String::Markov::sample_next_state which was called 136 times, avg 13µs/call:
# 136 times (1.71ms+3µs) by String::Markov::generate_sample at line 180, avg 13µs/call | ||||
145 | 136 | 97µs | my ($self, @cur_state) = @_; | ||
146 | 136 | 80µs | 1 | 600ns | die "ERR: wrong amount of state" if @cur_state != $self->order; # spent 600ns making 1 call to String::Markov::order |
147 | |||||
148 | 136 | 54µs | 1 | 800ns | my $count = $self->transition_count; # spent 800ns making 1 call to String::Markov::transition_count |
149 | 136 | 43µs | 1 | 800ns | my $sum = $self->row_sum; # spent 800ns making 1 call to String::Markov::row_sum |
150 | |||||
151 | 136 | 108µs | 1 | 600ns | my $cur = join($self->join_sep // '', @cur_state); # spent 600ns making 1 call to String::Markov::join_sep |
152 | 136 | 115µs | my $thresh = $sum->{$cur}; | ||
153 | 136 | 25µs | return undef if !$thresh; | ||
154 | |||||
155 | 136 | 121µs | $thresh *= rand(); | ||
156 | |||||
157 | 136 | 65µs | my $prob = $count->{$cur}; | ||
158 | 136 | 50µs | if (ref $prob ne 'ARRAY') { | ||
159 | $prob = $self->split_prob($prob); | ||||
160 | $count->{$cur} = $prob; | ||||
161 | } | ||||
162 | |||||
163 | 136 | 26µs | my $s = 0; | ||
164 | 136 | 22µs | my $i = 0; | ||
165 | 136 | 78µs | my ($k, $v) = @{$prob}; | ||
166 | 136 | 594µs | do { | ||
167 | $s += $v->[$i]; | ||||
168 | } while ($thresh > $s && ++$i); | ||||
169 | 136 | 403µs | return $k->[$i]; | ||
170 | } | ||||
171 | |||||
172 | # spent 2.35ms (635µs+1.72) within String::Markov::generate_sample which was called 7 times, avg 336µs/call:
# 6 times (580µs+1.55ms) by main::RUNTIME at line 46 of index.cgi, avg 355µs/call
# once (54µs+167µs) by main::RUNTIME at line 19 of index.cgi | ||||
173 | 7 | 4µs | my ($self) = @_; | ||
174 | |||||
175 | 7 | 13µs | 1 | 2µs | my $null = $self->null; # spent 2µs making 1 call to String::Markov::null |
176 | 7 | 10µs | 1 | 800ns | my $n = $self->order; # spent 800ns making 1 call to String::Markov::order |
177 | 7 | 10µs | 1 | 1µs | my $sep = $self->join_sep // ''; # spent 1µs making 1 call to String::Markov::join_sep |
178 | 7 | 9µs | my @nm = ($null,) x $n; | ||
179 | |||||
180 | 7 | 317µs | 136 | 1.71ms | do { # spent 1.71ms making 136 calls to String::Markov::sample_next_state, avg 13µs/call |
181 | push @nm, $self->sample_next_state(@nm[-$n .. -1]); | ||||
182 | } while ($nm[-1] ne $null); | ||||
183 | |||||
184 | 7 | 63µs | @nm = @nm[$n .. ($#nm-1)]; | ||
185 | |||||
186 | return wantarray ? | ||||
187 | 7 | 52µs | 1 | 800ns | @nm : # spent 800ns making 1 call to String::Markov::join_sep |
188 | defined $self->join_sep ? | ||||
189 | join($sep, @nm) : | ||||
190 | \@nm; | ||||
191 | |||||
192 | } | ||||
193 | |||||
194 | 1 | 10µs | 2 | 440µs | __PACKAGE__->meta->make_immutable; # spent 438µs making 1 call to Moo::Object::meta
# spent 2µs making 1 call to Moo::HandleMoose::FakeMetaClass::make_immutable |
195 | |||||
196 | 1 | 15µs | 1; | ||
197 | |||||
198 | 1 | 32µs | 1 | 2.39ms | __END__ # spent 2.39ms making 1 call to B::Hooks::EndOfScope::XS::__ANON__[B/Hooks/EndOfScope/XS.pm:17] |
# spent 7µs within String::Markov::CORE:match which was called 2 times, avg 4µs/call:
# 2 times (7µs+0s) by String::Markov::__ANON__[/usr/local/share/perl/5.18.2/String/Markov.pm:20] at line 19, avg 4µs/call | |||||
# spent 1.65ms within String::Markov::CORE:readline which was called 388 times, avg 4µs/call:
# 388 times (1.65ms+0s) by String::Markov::add_files at line 134, avg 4µs/call | |||||
# spent 301µs within String::Markov::CORE:regcomp which was called 386 times, avg 779ns/call:
# 386 times (301µs+0s) by String::Markov::split_line at line 90, avg 779ns/call | |||||
# spent 1.58ms within String::Markov::CORE:sort which was called 2703 times, avg 585ns/call:
# 2703 times (1.58ms+0s) by String::Markov::split_prob at line 60, avg 585ns/call | |||||
# spent 12µs within String::Markov::do_chomp which was called:
# once (12µs+0s) by String::Markov::add_files at line 131 | |||||
# spent 3µs within String::Markov::join_sep which was called 4 times, avg 875ns/call:
# once (1µs+0s) by String::Markov::generate_sample at line 177
# once (1µs+0s) by String::Markov::add_sample at line 112
# once (800ns+0s) by String::Markov::generate_sample at line 187
# once (600ns+0s) by String::Markov::sample_next_state at line 151 | |||||
# spent 700ns within String::Markov::normalize which was called:
# once (700ns+0s) by String::Markov::split_line at line 87 | |||||
sub String::Markov::null; # xsub | |||||
sub String::Markov::order; # xsub | |||||
sub String::Markov::row_sum; # xsub | |||||
sub String::Markov::split_sep; # xsub | |||||
# spent 1µs within String::Markov::stable which was called:
# once (1µs+0s) by String::Markov::split_prob at line 59 | |||||
sub String::Markov::transition_count; # xsub |