Filename | /usr/share/perl/5.20/File/Compare.pm |
Statements | Executed 79 statements in 955µs |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
2 | 1 | 1 | 90µs | 157µs | compare | File::Compare::
4 | 2 | 1 | 33µs | 33µs | CORE:open (opcode) | File::Compare::
1 | 1 | 1 | 24µs | 24µs | BEGIN@3 | File::Compare::
6 | 3 | 1 | 20µs | 20µs | CORE:read (opcode) | File::Compare::
1 | 1 | 1 | 12µs | 18µs | BEGIN@5 | File::Compare::
1 | 1 | 1 | 9µs | 18µs | BEGIN@4 | File::Compare::
4 | 4 | 1 | 8µs | 8µs | CORE:close (opcode) | File::Compare::
4 | 2 | 1 | 3µs | 3µs | CORE:binmode (opcode) | File::Compare::
4 | 2 | 1 | 2µs | 2µs | CORE:ftsize (opcode) | File::Compare::
0 | 0 | 0 | 0s | 0s | compare_text | File::Compare::
0 | 0 | 0 | 0s | 0s | croak | File::Compare::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | package File::Compare; | ||||
2 | |||||
3 | 2 | 51µs | 1 | 24µs | # spent 24µs within File::Compare::BEGIN@3 which was called:
# once (24µs+0s) by DateTime::TimeZone::Local::Unix::_FindMatchingZoneinfoFile at line 3 # spent 24µs making 1 call to File::Compare::BEGIN@3 |
4 | 2 | 36µs | 2 | 26µs | # spent 18µs (9+9) within File::Compare::BEGIN@4 which was called:
# once (9µs+9µs) by DateTime::TimeZone::Local::Unix::_FindMatchingZoneinfoFile at line 4 # spent 18µs making 1 call to File::Compare::BEGIN@4
# spent 9µs making 1 call to strict::import |
5 | 2 | 690µs | 2 | 24µs | # spent 18µs (12+6) within File::Compare::BEGIN@5 which was called:
# once (12µs+6µs) by DateTime::TimeZone::Local::Unix::_FindMatchingZoneinfoFile at line 5 # spent 18µs making 1 call to File::Compare::BEGIN@5
# spent 6µs making 1 call to warnings::import |
6 | 1 | 500ns | our($VERSION, @ISA, @EXPORT, @EXPORT_OK, $Too_Big); | ||
7 | |||||
8 | 1 | 1µs | require Exporter; | ||
9 | |||||
10 | 1 | 400ns | $VERSION = '1.1006'; | ||
11 | 1 | 8µs | @ISA = qw(Exporter); | ||
12 | 1 | 400ns | @EXPORT = qw(compare); | ||
13 | 1 | 400ns | @EXPORT_OK = qw(cmp compare_text); | ||
14 | |||||
15 | 1 | 200ns | $Too_Big = 1024 * 1024 * 2; | ||
16 | |||||
17 | sub croak { | ||||
18 | require Carp; | ||||
19 | goto &Carp::croak; | ||||
20 | } | ||||
21 | |||||
22 | # spent 157µs (90+67) within File::Compare::compare which was called 2 times, avg 78µs/call:
# 2 times (90µs+67µs) by File::Find::find at line 99 of DateTime/TimeZone/Local/Unix.pm, avg 78µs/call | ||||
23 | 2 | 600ns | croak("Usage: compare( file1, file2 [, buffersize]) ") | ||
24 | unless(@_ == 2 || @_ == 3); | ||||
25 | |||||
26 | 2 | 700ns | my ($from,$to,$size) = @_; | ||
27 | 2 | 800ns | my $text_mode = defined($size) && (ref($size) eq 'CODE' || $size < 0); | ||
28 | |||||
29 | 2 | 200ns | my ($fromsize,$closefrom,$closeto); | ||
30 | 2 | 2µs | local (*FROM, *TO); | ||
31 | |||||
32 | 2 | 200ns | croak("from undefined") unless (defined $from); | ||
33 | 2 | 200ns | croak("to undefined") unless (defined $to); | ||
34 | |||||
35 | 2 | 2µs | if (ref($from) && | ||
36 | (UNIVERSAL::isa($from,'GLOB') || UNIVERSAL::isa($from,'IO::Handle'))) { | ||||
37 | *FROM = *$from; | ||||
38 | } elsif (ref(\$from) eq 'GLOB') { | ||||
39 | *FROM = $from; | ||||
40 | } else { | ||||
41 | 2 | 29µs | 2 | 21µs | open(FROM,"<",$from) or goto fail_open1; # spent 21µs making 2 calls to File::Compare::CORE:open, avg 10µs/call |
42 | 2 | 700ns | unless ($text_mode) { | ||
43 | 2 | 8µs | 2 | 2µs | binmode FROM; # spent 2µs making 2 calls to File::Compare::CORE:binmode, avg 1µs/call |
44 | 2 | 6µs | 2 | 1µs | $fromsize = -s FROM; # spent 1µs making 2 calls to File::Compare::CORE:ftsize, avg 600ns/call |
45 | } | ||||
46 | 2 | 1µs | $closefrom = 1; | ||
47 | } | ||||
48 | |||||
49 | 2 | 2µs | if (ref($to) && | ||
50 | (UNIVERSAL::isa($to,'GLOB') || UNIVERSAL::isa($to,'IO::Handle'))) { | ||||
51 | *TO = *$to; | ||||
52 | } elsif (ref(\$to) eq 'GLOB') { | ||||
53 | *TO = $to; | ||||
54 | } else { | ||||
55 | 2 | 17µs | 2 | 12µs | open(TO,"<",$to) or goto fail_open2; # spent 12µs making 2 calls to File::Compare::CORE:open, avg 6µs/call |
56 | 2 | 5µs | 2 | 1µs | binmode TO unless $text_mode; # spent 1µs making 2 calls to File::Compare::CORE:binmode, avg 500ns/call |
57 | 2 | 1µs | $closeto = 1; | ||
58 | } | ||||
59 | |||||
60 | 2 | 1µs | if (!$text_mode && $closefrom && $closeto) { | ||
61 | # If both are opened files we know they differ if their size differ | ||||
62 | 2 | 5µs | 2 | 1µs | goto fail_inner if $fromsize != -s TO; # spent 1µs making 2 calls to File::Compare::CORE:ftsize, avg 650ns/call |
63 | } | ||||
64 | |||||
65 | 2 | 400ns | if ($text_mode) { | ||
66 | local $/ = "\n"; | ||||
67 | my ($fline,$tline); | ||||
68 | while (defined($fline = <FROM>)) { | ||||
69 | goto fail_inner unless defined($tline = <TO>); | ||||
70 | if (ref $size) { | ||||
71 | # $size contains ref to comparison function | ||||
72 | goto fail_inner if &$size($fline, $tline); | ||||
73 | } else { | ||||
74 | goto fail_inner if $fline ne $tline; | ||||
75 | } | ||||
76 | } | ||||
77 | goto fail_inner if defined($tline = <TO>); | ||||
78 | } | ||||
79 | else { | ||||
80 | 2 | 500ns | unless (defined($size) && $size > 0) { | ||
81 | 2 | 400ns | $size = $fromsize || -s TO || 0; | ||
82 | 2 | 400ns | $size = 1024 if $size < 512; | ||
83 | 2 | 400ns | $size = $Too_Big if $size > $Too_Big; | ||
84 | } | ||||
85 | |||||
86 | 2 | 200ns | my ($fr,$tr,$fbuf,$tbuf); | ||
87 | 2 | 700ns | $fbuf = $tbuf = ''; | ||
88 | 2 | 21µs | 2 | 13µs | while(defined($fr = read(FROM,$fbuf,$size)) && $fr > 0) { # spent 13µs making 2 calls to File::Compare::CORE:read, avg 6µs/call |
89 | 2 | 13µs | 3 | 6µs | unless (defined($tr = read(TO,$tbuf,$fr)) && $tbuf eq $fbuf) { # spent 6µs making 3 calls to File::Compare::CORE:read, avg 2µs/call |
90 | 1 | 7µs | goto fail_inner; | ||
91 | } | ||||
92 | } | ||||
93 | 1 | 5µs | 1 | 1µs | goto fail_inner if defined($tr = read(TO,$tbuf,$size)) && $tr > 0; # spent 1µs making 1 call to File::Compare::CORE:read |
94 | } | ||||
95 | |||||
96 | 1 | 6µs | 1 | 3µs | close(TO) || goto fail_open2 if $closeto; # spent 3µs making 1 call to File::Compare::CORE:close |
97 | 1 | 3µs | 1 | 1µs | close(FROM) || goto fail_open1 if $closefrom; # spent 1µs making 1 call to File::Compare::CORE:close |
98 | |||||
99 | 1 | 3µs | return 0; | ||
100 | |||||
101 | # All of these contortions try to preserve error messages... | ||||
102 | 1 | 9µs | 1 | 3µs | fail_inner: # spent 3µs making 1 call to File::Compare::CORE:close |
103 | close(TO) || goto fail_open2 if $closeto; | ||||
104 | 1 | 4µs | 1 | 2µs | close(FROM) || goto fail_open1 if $closefrom; # spent 2µs making 1 call to File::Compare::CORE:close |
105 | |||||
106 | 1 | 5µs | return 1; | ||
107 | |||||
108 | fail_open2: | ||||
109 | if ($closefrom) { | ||||
110 | my $status = $!; | ||||
111 | $! = 0; | ||||
112 | close FROM; | ||||
113 | $! = $status unless $!; | ||||
114 | } | ||||
115 | fail_open1: | ||||
116 | return -1; | ||||
117 | } | ||||
118 | |||||
119 | sub cmp; | ||||
120 | 1 | 2µs | *cmp = \&compare; | ||
121 | |||||
122 | sub compare_text { | ||||
123 | my ($from,$to,$cmp) = @_; | ||||
124 | croak("Usage: compare_text( file1, file2 [, cmp-function])") | ||||
125 | unless @_ == 2 || @_ == 3; | ||||
126 | croak("Third arg to compare_text() function must be a code reference") | ||||
127 | if @_ == 3 && ref($cmp) ne 'CODE'; | ||||
128 | |||||
129 | # Using a negative buffer size puts compare into text_mode too | ||||
130 | $cmp = -1 unless defined $cmp; | ||||
131 | compare($from, $to, $cmp); | ||||
132 | } | ||||
133 | |||||
134 | 1 | 5µs | 1; | ||
135 | |||||
136 | __END__ | ||||
sub File::Compare::CORE:binmode; # opcode | |||||
# spent 8µs within File::Compare::CORE:close which was called 4 times, avg 2µs/call:
# once (3µs+0s) by File::Compare::compare at line 102
# once (3µs+0s) by File::Compare::compare at line 96
# once (2µs+0s) by File::Compare::compare at line 104
# once (1µs+0s) by File::Compare::compare at line 97 | |||||
sub File::Compare::CORE:ftsize; # opcode | |||||
sub File::Compare::CORE:open; # opcode | |||||
sub File::Compare::CORE:read; # opcode |