File Coverage

blib/lib/Log/Defer/Viz.pm
Criterion Covered Total %
statement 64 64 100.0
branch 14 14 100.0
condition 11 13 84.6
subroutine 4 4 100.0
pod 0 1 0.0
total 93 96 96.8


line stmt bran cond sub pod time code
1             package Log::Defer::Viz;
2              
3             our $VERSION = '0.347';
4              
5 2     2   26752 use common::sense;
  2         14  
  2         7  
6              
7 2     2   80 use Carp qw/croak/;
  2         1  
  2         1171  
8              
9              
10              
11              
12             sub render_timers {
13 3     3 0 101 my %arg = @_;
14              
15 3   100     12 my $width = $arg{width} || 80;
16 3   33     6 my $timers = $arg{timers} || croak "need timers";
17              
18             ## Support old style timers where they were stored in a hash:
19              
20 3 100       9 if (ref $timers eq 'HASH') {
21 1         2 my $temp_timers = [];
22              
23 1         3 foreach my $timer_name (keys %$timers) {
24 2         3 push @$temp_timers, [ $timer_name, @{ $timers->{$timer_name} }, ];
  2         4  
25             }
26              
27 1         2 $timers = $temp_timers;
28             }
29              
30 3         10 my @sorted_timers = sort { $a->[1] <=> $b->[1] } @$timers;
  11         14  
31 3         5 my @sorted_timers_by_end_time = sort { $a->[2] <=> $b->[2] } @$timers;
  13         14  
32              
33 3         3 my $output = '';
34              
35              
36             ## Scan some information
37              
38 3         2 my $max_time = 0;
39 3         3 my $max_namelen = 11;
40              
41 3         4 foreach my $timer (@sorted_timers) {
42 10 100       17 $max_time = $timer->[2] if $timer->[2] > $max_time;
43 10 100       17 $max_namelen = length($timer->[0])+1 if length($timer->[0])+1 > $max_namelen;
44             }
45              
46              
47             ## Bar graph plots
48              
49 3         7 my $scaling = ($width - $max_namelen - 8) / $max_time;
50              
51 3         3 foreach my $timer (@sorted_timers) {
52 10         22 $output .= sprintf("%${max_namelen}s ", $timer->[0]);
53              
54 10         16 $output .= ' ' x int($timer->[1] * $scaling);
55              
56 10         12 my $bar_width = int(($timer->[2] - $timer->[1]) * $scaling) - 1;
57              
58 10 100       29 if ($bar_width > 0) {
59 9         6 $output .= '|';
60 9         13 $output .= '=' x $bar_width;
61 9         9 $output .= '|';
62             } else {
63 1         2 $output .= 'X';
64             }
65              
66 10         11 $output .= "\n";
67             }
68              
69              
70 3         6 $output .= '_' x $width . "\n";
71              
72              
73             ## Time legend
74              
75 3         4 my $seen = {};
76              
77 3         4 $output .= 'times in ms ';
78 3         5 $output .= ' ' x ($max_namelen - 11);
79 3         4 $output .= _time_bars($max_time, $scaling, [ map { $_->[1] } @sorted_timers ], $seen);
  10         16  
80              
81 3         7 $output .= ' ' x ($max_namelen + 1);
82 3         5 $output .= _time_bars($max_time, $scaling, [ map { $_->[2] } @sorted_timers_by_end_time ], $seen);
  10         11  
83              
84 3         70 return $output;
85             }
86              
87              
88              
89             sub _time_bars {
90 6     6   8 my ($max_time, $scaling, $vals, $seen) = @_;
91              
92 6         6 my $output = '';
93              
94 6         4 my $last_time;
95 6         4 my $last_time_str_len = 0;
96              
97 6         7 foreach my $val (@$vals) {
98 20 100 100     59 next if defined $last_time &&
99             (abs($last_time - $val) / $max_time) < 0.05;
100              
101 16   100     36 my $sep_len = int($scaling * ($val - ($last_time || 0))) - $last_time_str_len;
102 16 100 100     32 $sep_len = 1 if $sep_len < 1 && defined $last_time;
103 16         16 $output .= ' ' x $sep_len;
104              
105 16         54 my $time_str = sprintf("%.1f", $val * 1000);
106              
107 16 100       21 if ($seen->{$time_str}) {
108 2         9 $last_time_str_len = 0;
109             } else {
110 14         10 $output .= $time_str;
111 14         11 $last_time_str_len = length($time_str);
112 14         44 $seen->{$time_str} = 1;
113             }
114              
115 16         14 $last_time = $val;
116             }
117              
118 6         5 $output .= "\n";
119              
120 6         11 return $output
121             }
122              
123              
124             1;
125              
126              
127              
128              
129             __END__