← Index
NYTProf Performance Profile   « line view »
For /home/ss5/perl5/perlbrew/perls/perl-5.22.0/bin/benchmarkanything-storage
  Run on Mon Jan 29 16:55:34 2018
Reported on Mon Jan 29 16:57:07 2018

Filename/home/ss5/perl5/perlbrew/perls/perl-5.22.0/lib/site_perl/5.22.0/CHI/Stats.pm
StatementsExecuted 18 statements in 758µs
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
1112.12ms7.16msCHI::Stats::::BEGIN@6CHI::Stats::BEGIN@6
111714µs8.55msCHI::Stats::::BEGIN@3CHI::Stats::BEGIN@3
111426µs3.30msCHI::Stats::::BEGIN@5CHI::Stats::BEGIN@5
11114µs19µsCHI::Stats::::BEGIN@8CHI::Stats::BEGIN@8
1119µs29µsCHI::Stats::::BEGIN@4CHI::Stats::BEGIN@4
1115µs6µsCHI::Stats::::BEGIN@7CHI::Stats::BEGIN@7
0000s0sCHI::Stats::::__ANON__[:114]CHI::Stats::__ANON__[:114]
0000s0sCHI::Stats::::__ANON__[:11]CHI::Stats::__ANON__[:11]
0000s0sCHI::Stats::::__ANON__[:12]CHI::Stats::__ANON__[:12]
0000s0sCHI::Stats::::__ANON__[:131]CHI::Stats::__ANON__[:131]
0000s0sCHI::Stats::::__ANON__[:13]CHI::Stats::__ANON__[:13]
0000s0sCHI::Stats::::clearCHI::Stats::clear
0000s0sCHI::Stats::::disableCHI::Stats::disable
0000s0sCHI::Stats::::enableCHI::Stats::enable
0000s0sCHI::Stats::::flushCHI::Stats::flush
0000s0sCHI::Stats::::format_timeCHI::Stats::format_time
0000s0sCHI::Stats::::log_namespace_statsCHI::Stats::log_namespace_stats
0000s0sCHI::Stats::::parse_stats_logsCHI::Stats::parse_stats_logs
0000s0sCHI::Stats::::stats_for_driverCHI::Stats::stats_for_driver
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1package CHI::Stats;
21400ns$CHI::Stats::VERSION = '0.60';
3262µs28.58ms
# spent 8.55ms (714µs+7.83) within CHI::Stats::BEGIN@3 which was called: # once (714µs+7.83ms) by CHI::BEGIN@5 at line 3
use CHI::Util qw(json_encode json_decode);
# spent 8.55ms making 1 call to CHI::Stats::BEGIN@3 # spent 32µs making 1 call to Exporter::import
4219µs236µs
# spent 29µs (9+20) within CHI::Stats::BEGIN@4 which was called: # once (9µs+20µs) by CHI::BEGIN@5 at line 4
use List::Util qw(sum);
# spent 29µs making 1 call to CHI::Stats::BEGIN@4 # spent 7µs making 1 call to List::Util::import
5252µs24.53ms
# spent 3.30ms (426µs+2.87) within CHI::Stats::BEGIN@5 which was called: # once (426µs+2.87ms) by CHI::BEGIN@5 at line 5
use Log::Any qw($log);
# spent 3.30ms making 1 call to CHI::Stats::BEGIN@5 # spent 1.23ms making 1 call to Log::Any::import
6260µs28.34ms
# spent 7.16ms (2.12+5.04) within CHI::Stats::BEGIN@6 which was called: # once (2.12ms+5.04ms) by CHI::BEGIN@5 at line 6
use Moo;
# spent 7.16ms making 1 call to CHI::Stats::BEGIN@6 # spent 1.18ms making 1 call to Moo::import
7212µs27µs
# spent 6µs (5+1) within CHI::Stats::BEGIN@7 which was called: # once (5µs+1µs) by CHI::BEGIN@5 at line 7
use strict;
# spent 6µs making 1 call to CHI::Stats::BEGIN@7 # spent 1µs making 1 call to strict::import
82536µs224µs
# spent 19µs (14+5) within CHI::Stats::BEGIN@8 which was called: # once (14µs+5µs) by CHI::BEGIN@5 at line 8
use warnings;
# spent 19µs making 1 call to CHI::Stats::BEGIN@8 # spent 5µs making 1 call to warnings::import
9
1012µs110.6mshas 'chi_root_class' => ( is => 'ro' );
# spent 10.6ms making 1 call to Moo::has
1115µs197µshas 'data' => ( is => 'ro', default => sub { {} } );
# spent 97µs making 1 call to Moo::has
1212µs1117µshas 'enabled' => ( is => 'rwp', default => sub { 0 } );
# spent 117µs making 1 call to Moo::has
1312µs175µshas 'start_time' => ( is => 'ro', default => sub { time } );
# spent 75µs making 1 call to Moo::has
14
15sub enable { $_[0]->_set_enabled(1) }
16sub disable { $_[0]->_set_enabled(0) }
17
18sub flush {
19 my ($self) = @_;
20
21 my $data = $self->data;
22 foreach my $label ( sort keys %$data ) {
23 my $label_stats = $data->{$label};
24 foreach my $namespace ( sort keys(%$label_stats) ) {
25 my $namespace_stats = $label_stats->{$namespace};
26 if (%$namespace_stats) {
27 $self->log_namespace_stats( $label, $namespace,
28 $namespace_stats );
29 }
30 }
31 }
32 $self->clear();
33}
34
35sub log_namespace_stats {
36 my ( $self, $label, $namespace, $namespace_stats ) = @_;
37
38 my %data = (
39 label => $label,
40 end_time => time(),
41 namespace => $namespace,
42 root_class => $self->chi_root_class,
43 %$namespace_stats
44 );
45 %data =
46 map { /_ms$/ ? ( $_, int( $data{$_} ) ) : ( $_, $data{$_} ) }
47 keys(%data);
48 $log->infof( 'CHI stats: %s', json_encode( \%data ) );
49}
50
51sub format_time {
52 my ($time) = @_;
53
54 my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) =
55 localtime($time);
56 return sprintf(
57 "%04d%02d%02d:%02d:%02d:%02d",
58 $year + 1900,
59 $mon + 1, $mday, $hour, $min, $sec
60 );
61}
62
63sub stats_for_driver {
64 my ( $self, $cache ) = @_;
65
66 my $stats =
67 ( $self->data->{ $cache->label }->{ $cache->namespace } ||= {} );
68 $stats->{start_time} ||= time;
69 return $stats;
70}
71
72sub parse_stats_logs {
73 my $self = shift;
74 my ( %results_hash, @results, %numeric_fields_seen );
75 foreach my $log_file (@_) {
76 my $logfh;
77 if ( ref($log_file) ) {
78 $logfh = $log_file;
79 }
80 else {
81 open( $logfh, '<', $log_file ) or die "cannot open $log_file: $!";
82 $log->infof( "processing '%s'", $log_file );
83 }
84 while ( my $line = <$logfh> ) {
85 chomp($line);
86 if ( my ($json) = ( $line =~ /CHI stats: (\{.*\})$/ ) ) {
87 my %hash = %{ json_decode($json) };
88 my $root_class = delete( $hash{root_class} );
89 my $namespace = delete( $hash{namespace} );
90 my $label = delete( $hash{label} );
91 my $results_set =
92 ( $results_hash{$root_class}->{$label}->{$namespace} ||= {} );
93 if ( !%$results_set ) {
94 $results_set->{root_class} = $root_class;
95 $results_set->{namespace} = $namespace;
96 $results_set->{label} = $label;
97 push( @results, $results_set );
98 }
99 while ( my ( $key, $value ) = each(%hash) ) {
100 next if $key =~ /_time$/;
101 $results_set->{$key} += $value;
102 $numeric_fields_seen{$key}++;
103 }
104 }
105 }
106 }
107 my @numeric_fields = sort( keys(%numeric_fields_seen) );
108
109 my $sum = sub {
110 my ( $rs, $name, @fields ) = @_;
111 if ( grep { $rs->{$_} } @fields ) {
112 $rs->{$name} = sum( map { $rs->{$_} || 0 } @fields );
113 }
114 };
115 foreach my $rs (@results) {
116 $sum->( $rs, 'misses', 'absent_misses', 'expired_misses' );
117 $sum->( $rs, 'gets', 'hits', 'misses' );
118 }
119
120 my %totals = map { ( $_, 'TOTALS' ) } qw(root_class namespace label);
121 foreach my $field (@numeric_fields) {
122 $totals{$field} = sum( map { $_->{$field} || 0 } @results );
123 }
124 push( @results, \%totals );
125
126 my $divide = sub {
127 my ( $rs, $name, $top, $bottom ) = @_;
128 if ( $rs->{$top} && $rs->{$bottom} ) {
129 $rs->{$name} = ( $rs->{$top} / $rs->{$bottom} );
130 }
131 };
132
133 foreach my $rs (@results) {
134 $divide->( $rs, 'avg_compute_time_ms', 'compute_time_ms', 'computes' );
135 $divide->( $rs, 'avg_get_time_ms', 'get_time_ms', 'gets' );
136 $divide->( $rs, 'avg_set_time_ms', 'set_time_ms', 'sets' );
137 $divide->( $rs, 'avg_set_key_size', 'set_key_size', 'sets' );
138 $divide->( $rs, 'avg_set_value_size', 'set_value_size', 'sets' );
139 $divide->( $rs, 'hit_rate', 'hits', 'gets' );
140 }
141 return \@results;
142}
143
144sub clear {
145 my ($self) = @_;
146
147 my $data = $self->data;
148 foreach my $key ( keys %{$data} ) {
149 %{ $data->{$key} } = ();
150 }
151 $self->{start_time} = time;
152}
153
15416µs1;
155
156__END__