File Coverage

blib/lib/Time/StopWatchWithMessage.pm
Criterion Covered Total %
statement 16 75 21.3
branch 0 12 0.0
condition 0 8 0.0
subroutine 6 15 40.0
pod 6 7 85.7
total 28 117 23.9


line stmt bran cond sub pod time code
1             package Time::StopWatchWithMessage;
2 3     3   2181 use strict;
  3         6  
  3         127  
3 3     3   16 use warnings;
  3         5  
  3         138  
4 3     3   29 use List::Util qw( sum max reduce );
  3         6  
  3         405  
5 3     3   2799 use List::MoreUtils qw( first_index );
  3         3453  
  3         232  
6 3     3   2556 use Time::HiRes qw( gettimeofday tv_interval );
  3         5322  
  3         16  
7              
8             our $VERSION = "0.06";
9             our $IS_REALTIME = 0;
10             our $LENGTH = 3;
11              
12 1     1 0 87 sub new { bless [ ], shift }
13              
14             sub start {
15 0     0 1   my $self = shift;
16 0   0       my $message = shift || __PACKAGE__ . ">>> Start watching.";
17              
18 0 0         $self->stop
19             if $self->_does_stop_need;
20              
21 0           push @{ $self }, { time => [ gettimeofday ], message => $message };
  0            
22              
23 0           return $self;
24             }
25              
26             sub stop {
27 0     0 1   my $self = shift;
28 0           my $time = [ gettimeofday ];
29              
30 0           my $previous = pop @{ $self };
  0            
31 0           $previous->{time} = tv_interval( $previous->{time}, $time );
32              
33 0           push @{ $self }, $previous;
  0            
34              
35 0 0         if ( $IS_REALTIME ) {
36 0           warn sprintf "%s - %.${LENGTH}f[s]\n", $previous->{message}, $previous->{time};
37             }
38              
39 0           return $self;
40             }
41              
42             sub _does_stop_need {
43 0     0     my $self = shift;
44 0   0       return @{ $self } && ref $self->[-1]{time} eq ref [ ];
45             }
46              
47             sub collapse {
48 0     0 1   my $self = shift;
49              
50 0 0         $self->stop
51             if $self->_does_stop_need;
52              
53             my $watches_ref = reduce {
54 0     0     my $i = first_index { $_->{message} eq $b->{message} } @{ $a };
  0            
  0            
55              
56 0 0         if ( $i >= 0 ) {
57 0           $a->[ $i ]{time} += $b->{time};
58 0           $a->[ $i ]{count}++;
59             }
60             else {
61 0           push @{ $a }, $b;
  0            
62             }
63              
64 0           $a;
65 0           } ( [ ], @{ $self } );
  0            
66              
67 0           return bless $watches_ref, ref $self;
68             }
69              
70             sub _output {
71 0     0     my $self = shift;
72 0           my $FH = shift;
73              
74 0 0         $self->stop
75             if $self->_does_stop_need;
76              
77 0           my $sum = sum( map { $_->{time} } @{ $self } );
  0            
  0            
78 0           my $max = max( map { $_->{time} } @{ $self } );
  0            
  0            
79 0           my %length = (
80 0           time => max( map { length int $_->{time} } @{ $self } ),
  0            
81 0           message => max( map { length $_->{message} } @{ $self } ),
  0            
82             );
83              
84 0           OUTPUT_ALL_WATCHES:
85 0           while ( defined( my $watch_ref = shift @{ $self } ) ) {
86 0           my $output = sprintf(
87             "%$length{message}s - %$length{time}.${LENGTH}f[s] / %$length{time}.${LENGTH}f[s] = %$length{time}.${LENGTH}f[%%]",
88             $watch_ref->{message},
89             $watch_ref->{time},
90             $sum,
91             $watch_ref->{time} / $sum * 100,
92             );
93              
94 0 0         if ( $watch_ref->{count} ) {
95 0           $output = join q{; }, $output, sprintf "%d times measured.", $watch_ref->{count} + 1;
96             }
97              
98 0           print { $FH } $output, "\n";
  0            
99             }
100              
101 0           return;
102             }
103              
104             sub output {
105 0     0 1   my $self = shift;
106 0   0       my $FH = shift || *STDERR;
107              
108 0           return $self->_output( $FH );
109             }
110              
111 0     0 1   sub print { shift->_output( *STDOUT ) }
112              
113 0     0 1   sub warn { shift->_output( *STDERR ) }
114              
115             1;
116              
117             __END__