line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Time::Stats; |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
=head1 NAME |
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
Time::Stats - Easy timing info |
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
=head1 SYNOPSIS |
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
use Time::Stats; |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
clear(); |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
mark(); |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
stats(); |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
# If you don't want to import the above methods: |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
use Time::Stats (); |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
Time::Stats::clear(); |
22
|
|
|
|
|
|
|
Time::Stats::mark(); |
23
|
|
|
|
|
|
|
Time::Stats::stats(); |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
=head1 DESCRIPTION |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
This module is designed to make it very easy to get timing info for your code, ala Time::HiRes, without needing to remember tv_interval and [gettimeofday], or writing your own methods for processing data. This is mainly useful if DProf doesn't give you useful info on what's slowing you down, and you need to inspect larger sections of code. |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
It's pretty smart about loops and being used in persistent environments such as mod_perl. |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
=cut |
32
|
|
|
|
|
|
|
|
33
|
1
|
|
|
1
|
|
23992
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
39
|
|
34
|
1
|
|
|
1
|
|
6
|
use warnings; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
39
|
|
35
|
|
|
|
|
|
|
|
36
|
1
|
|
|
1
|
|
3521
|
use Time::HiRes qw(tv_interval gettimeofday); |
|
1
|
|
|
|
|
3583
|
|
|
1
|
|
|
|
|
4
|
|
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
require Exporter; |
39
|
|
|
|
|
|
|
our @ISA = qw(Exporter); |
40
|
|
|
|
|
|
|
our @EXPORT = qw(mark clear stats); |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
our $VERSION = '1.0'; |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
our %mark_names; |
45
|
|
|
|
|
|
|
our %last_caller_data; |
46
|
|
|
|
|
|
|
our %time_data; |
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
=over 4 |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
=item mark( [$name] ) |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
Flags a point in the code to pay attention to. Times will be reported for the code in between two calls to mark within the same file. If the calls to mark are inside of a loop, the times between two calls to mark will be summed. |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
Takes an optional scalar mark name which will label the time that this mark completes in the output generated by stats(). If no name is passed, output will be labeled by line number. |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
=cut |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
sub mark { |
59
|
0
|
|
|
0
|
1
|
|
my $name = shift; |
60
|
0
|
|
|
|
|
|
my @caller = caller; |
61
|
|
|
|
|
|
|
|
62
|
0
|
|
|
|
|
|
my $file = $caller[1]; |
63
|
0
|
|
|
|
|
|
my $line = $caller[2]; |
64
|
|
|
|
|
|
|
|
65
|
0
|
|
|
|
|
|
my $current_time = [gettimeofday]; |
66
|
|
|
|
|
|
|
# if you're using mod_perl, or what not, you don't want line 99 to 40 taking up 40 seconds and messing up your numbers! |
67
|
0
|
0
|
0
|
|
|
|
if ($last_caller_data{$file} && ($last_caller_data{$file}->{'line'} < $line)) { |
68
|
0
|
|
|
|
|
|
my $start_line = $last_caller_data{$file}->{'line'}; |
69
|
0
|
|
|
|
|
|
my $last_time = $last_caller_data{$file}->{'time'}; |
70
|
0
|
|
|
|
|
|
$time_data{$file}->{$start_line.'-'.$line} += tv_interval($last_time, $current_time); |
71
|
0
|
0
|
|
|
|
|
$mark_names{$file}->{$start_line.'-'.$line} = $name if $name; |
72
|
|
|
|
|
|
|
} |
73
|
0
|
|
|
|
|
|
$last_caller_data{$file}->{'line'} = $line; |
74
|
0
|
|
|
|
|
|
$last_caller_data{$file}->{'time'} = $current_time; |
75
|
|
|
|
|
|
|
|
76
|
0
|
|
|
|
|
|
return; |
77
|
|
|
|
|
|
|
} |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
=item clear() |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
Removes all data currently tracked, in all files. |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
=cut |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
sub clear { |
86
|
0
|
|
|
0
|
1
|
|
%last_caller_data = (); |
87
|
0
|
|
|
|
|
|
%time_data = (); |
88
|
0
|
|
|
|
|
|
%mark_names = (); |
89
|
|
|
|
|
|
|
} |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
=item stats() |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
Prints a synopsis to STDERR. This displays time per file, with the slowest intervals sorted to the top of each file. |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
=cut |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
sub stats { |
98
|
0
|
|
|
0
|
1
|
|
foreach my $file (keys %time_data) { |
99
|
0
|
|
|
|
|
|
print STDERR "File: $file\n"; |
100
|
0
|
|
|
|
|
|
foreach my $lines (sort { $time_data{$file}->{$b} <=> $time_data{$file}->{$a} } keys %{$time_data{$file}}) { |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
101
|
0
|
|
|
|
|
|
my $duration = $time_data{$file}->{$lines}; |
102
|
0
|
|
|
|
|
|
my ($start, $end) = split(/-/, $lines); |
103
|
0
|
0
|
|
|
|
|
if(my $mark_name = $mark_names{$file}->{$lines}){ |
104
|
0
|
|
|
|
|
|
print STDERR "Mark $mark_name: $duration\n"; |
105
|
|
|
|
|
|
|
}else{ |
106
|
0
|
|
|
|
|
|
print STDERR "Lines $start to $end: $duration\n"; |
107
|
|
|
|
|
|
|
} |
108
|
|
|
|
|
|
|
} |
109
|
|
|
|
|
|
|
} |
110
|
|
|
|
|
|
|
} |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
=back |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
=cut |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
1; |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
__END__ |