Filename | /zpool_host_mnt/mnt/home/s1/repos/perl-JSON-Decode-Regexp/lib/JSON/Decode/Regexp.pm |
Statements | Executed 5011 statements in 114ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
1000 | 1 | 1 | 91.2ms | 91.2ms | CORE:regcomp (opcode) | JSON::Decode::Regexp::
1000 | 1 | 1 | 9.39ms | 109ms | from_json | JSON::Decode::Regexp::
1000 | 1 | 1 | 8.68ms | 8.68ms | CORE:match (opcode) | JSON::Decode::Regexp::
1 | 1 | 1 | 2.52ms | 2.57ms | BEGIN@8 | JSON::Decode::Regexp::
1 | 1 | 1 | 616µs | 701µs | BEGIN@7 | JSON::Decode::Regexp::
1 | 1 | 1 | 28µs | 28µs | BEGIN@6 | JSON::Decode::Regexp::
1 | 1 | 1 | 9µs | 9µs | CORE:qr (opcode) | JSON::Decode::Regexp::
0 | 0 | 0 | 0s | 0s | __ANON__[lib/JSON/Decode/Regexp.pm:142] | JSON::Decode::Regexp::
0 | 0 | 0 | 0s | 0s | _fail | JSON::Decode::Regexp::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | package JSON::Decode::Regexp; | ||||
2 | |||||
3 | # DATE | ||||
4 | # VERSION | ||||
5 | |||||
6 | 2 | 56µs | 1 | 28µs | # spent 28µs within JSON::Decode::Regexp::BEGIN@6 which was called:
# once (28µs+0s) by main::BEGIN@0 at line 6 # spent 28µs making 1 call to JSON::Decode::Regexp::BEGIN@6 |
7 | 2 | 431µs | 2 | 706µs | # spent 701µs (616+85) within JSON::Decode::Regexp::BEGIN@7 which was called:
# once (616µs+85µs) by main::BEGIN@0 at line 7 # spent 701µs making 1 call to JSON::Decode::Regexp::BEGIN@7
# spent 5µs making 1 call to strict::import |
8 | 2 | 3.05ms | 2 | 2.59ms | # spent 2.57ms (2.52+54µs) within JSON::Decode::Regexp::BEGIN@8 which was called:
# once (2.52ms+54µs) by main::BEGIN@0 at line 8 # spent 2.57ms making 1 call to JSON::Decode::Regexp::BEGIN@8
# spent 17µs making 1 call to warnings::import |
9 | |||||
10 | #use Data::Dumper; | ||||
11 | |||||
12 | 1 | 788µs | require Exporter; | ||
13 | 1 | 12µs | our @ISA = qw(Exporter); | ||
14 | 1 | 1µs | our @EXPORT_OK = qw(from_json); | ||
15 | |||||
16 | sub _fail { die __PACKAGE__.": $_[0] at offset ".pos()."\n" } | ||||
17 | |||||
18 | our $FROM_JSON = qr{ | ||||
19 | |||||
20 | (?: | ||||
21 | 1000 | 7.10ms | (?&VALUE) (?{ $_ = $^R->[1] }) | ||
22 | | | ||||
23 | \z (?{ _fail "Unexpected end of input" }) | ||||
24 | | | ||||
25 | (?{ _fail "Invalid literal" }) | ||||
26 | ) | ||||
27 | |||||
28 | (?(DEFINE) | ||||
29 | |||||
30 | (?<OBJECT> | ||||
31 | \{\s* | ||||
32 | (?{ [$^R, {}] }) | ||||
33 | (?: | ||||
34 | (?&KV) # [[$^R, {}], $k, $v] | ||||
35 | (?{ [$^R->[0][0], {$^R->[1] => $^R->[2]}] }) | ||||
36 | \s* | ||||
37 | (?: | ||||
38 | (?: | ||||
39 | ,\s* (?&KV) # [[$^R, {...}], $k, $v] | ||||
40 | (?{ $^R->[0][1]{ $^R->[1] } = $^R->[2]; $^R->[0] }) | ||||
41 | )* | ||||
42 | | | ||||
43 | (?:[^,\}]|\z) (?{ _fail "Expected ',' or '\x7d'" }) | ||||
44 | )* | ||||
45 | )? | ||||
46 | \s* | ||||
47 | (?: | ||||
48 | \} | ||||
49 | | | ||||
50 | (?:.|\z) (?{ _fail "Expected closing of hash" }) | ||||
51 | ) | ||||
52 | ) | ||||
53 | |||||
54 | (?<KV> | ||||
55 | (?&STRING) # [$^R, "string"] | ||||
56 | \s* | ||||
57 | (?: | ||||
58 | :\s* (?&VALUE) # [[$^R, "string"], $value] | ||||
59 | (?{ [$^R->[0][0], $^R->[0][1], $^R->[1]] }) | ||||
60 | | | ||||
61 | (?:[^:]|\z) (?{ _fail "Expected ':'" }) | ||||
62 | ) | ||||
63 | ) | ||||
64 | |||||
65 | (?<ARRAY> | ||||
66 | \[\s* | ||||
67 | (?{ [$^R, []] }) | ||||
68 | (?: | ||||
69 | (?&VALUE) # [[$^R, []], $val] | ||||
70 | (?{ [$^R->[0][0], [$^R->[1]]] }) | ||||
71 | \s* | ||||
72 | (?: | ||||
73 | (?: | ||||
74 | ,\s* (?&VALUE) | ||||
75 | (?{ push @{$^R->[0][1]}, $^R->[1]; $^R->[0] }) | ||||
76 | )* | ||||
77 | | | ||||
78 | (?: [^,\]]|\z ) (?{ _fail "Expected ',' or '\x5d'" }) | ||||
79 | ) | ||||
80 | )? | ||||
81 | \s* | ||||
82 | (?: | ||||
83 | \] | ||||
84 | | | ||||
85 | (?:.|\z) (?{ _fail "Expected closing of array" }) | ||||
86 | ) | ||||
87 | ) | ||||
88 | |||||
89 | (?<VALUE> | ||||
90 | \s* | ||||
91 | ( | ||||
92 | (?&STRING) | ||||
93 | | | ||||
94 | (?&NUMBER) | ||||
95 | | | ||||
96 | (?&OBJECT) | ||||
97 | | | ||||
98 | (?&ARRAY) | ||||
99 | | | ||||
100 | true (?{ [$^R, 1] }) | ||||
101 | | | ||||
102 | false (?{ [$^R, 0] }) | ||||
103 | | | ||||
104 | null (?{ [$^R, undef] }) | ||||
105 | ) | ||||
106 | \s* | ||||
107 | ) | ||||
108 | |||||
109 | (?<STRING> | ||||
110 | ( | ||||
111 | " | ||||
112 | (?: | ||||
113 | [^\\"]+ | ||||
114 | | | ||||
115 | \\ ["\\/bfnrt] | ||||
116 | # | | ||||
117 | # \\ u [0-9a-fA-f]{4} | ||||
118 | | | ||||
119 | \\ . (?{ _fail "Invalid string escape character" }) | ||||
120 | )* | ||||
121 | (?: | ||||
122 | " | ||||
123 | | | ||||
124 | (?:\\|\z) (?{ _fail "Expected closing of string" }) | ||||
125 | ) | ||||
126 | ) | ||||
127 | |||||
128 | (?{ [$^R, eval $^N] }) | ||||
129 | ) | ||||
130 | |||||
131 | (?<NUMBER> | ||||
132 | ( | ||||
133 | -? | ||||
134 | (?: 0 | [1-9]\d* ) | ||||
135 | (?: \. \d+ )? | ||||
136 | (?: [eE] [-+]? \d+ )? | ||||
137 | ) | ||||
138 | |||||
139 | (?{ [$^R, 0+$^N] }) | ||||
140 | ) | ||||
141 | |||||
142 | 1 | 21µs | 1 | 9µs | ) }xms; # spent 9µs making 1 call to JSON::Decode::Regexp::CORE:qr |
143 | |||||
144 | # spent 109ms (9.39+99.9) within JSON::Decode::Regexp::from_json which was called 1000 times, avg 109µs/call:
# 1000 times (9.39ms+99.9ms) by main::RUNTIME at line 1 of -e, avg 109µs/call | ||||
145 | 1000 | 340µs | local $_ = shift; | ||
146 | 1000 | 102µs | local $^R; | ||
147 | 2000 | 102ms | 2000 | 99.9ms | eval { m{\A$FROM_JSON\z}; } and return $_; # spent 91.2ms making 1000 calls to JSON::Decode::Regexp::CORE:regcomp, avg 91µs/call
# spent 8.68ms making 1000 calls to JSON::Decode::Regexp::CORE:match, avg 9µs/call |
148 | die $@ if $@; | ||||
149 | die 'no match'; | ||||
150 | } | ||||
151 | |||||
152 | 1 | 6µs | 1; | ||
153 | # ABSTRACT: JSON parser as a single Perl Regex | ||||
154 | |||||
155 | =head1 SYNOPSIS | ||||
156 | |||||
157 | use JSON::Decode::Regexp qw(from_json); | ||||
158 | my $data = from_json(q([1, true, "a", {"b":null}])); | ||||
159 | |||||
160 | |||||
161 | =head1 DESCRIPTION | ||||
162 | |||||
163 | This module is a packaging of Randal L. Schwartz' code (with some modification) | ||||
164 | originally posted at: | ||||
165 | |||||
166 | http://perlmonks.org/?node_id=995856 | ||||
167 | |||||
168 | The code is licensed "just like Perl". | ||||
169 | |||||
170 | |||||
171 | =head1 FUNCTIONS | ||||
172 | |||||
173 | =head2 from_json($str) => DATA | ||||
174 | |||||
175 | Decode JSON in C<$str>. Dies on error. | ||||
176 | |||||
177 | |||||
178 | =head1 FAQ | ||||
179 | |||||
180 | =head2 How does this module compare to other JSON modules on CPAN? | ||||
181 | |||||
182 | As of version 0.04, performance-wise this module quite on par with L<JSON::PP> | ||||
183 | (faster on strings and longer arrays/objects, slower on simpler JSON) and a bit | ||||
184 | slower than L<JSON::Tiny>. And of course all three are much slower than XS-based | ||||
185 | modules like L<JSON::XS>. | ||||
186 | |||||
187 | JSON::Decode::Regexp does not yet support Unicode, and does not pinpoint exact | ||||
188 | location on parse error. | ||||
189 | |||||
190 | In general, I don't see a point in using it in production (I recommend instead | ||||
191 | L<JSON::XS> or L<Cpanel::JSON::XS> if you can use XS modules, or L<JSON::Tiny> | ||||
192 | if you must use pure Perl modules). But it is a cool hack that demonstrates the | ||||
193 | power of Perl regular expressions and beautiful code. | ||||
194 | |||||
195 | |||||
196 | =head1 SEE ALSO | ||||
197 | |||||
198 | Pure-perl modules: L<JSON::Tiny>, L<JSON::PP>, L<Pegex::JSON>, | ||||
199 | L<JSON::Decode::Marpa>. | ||||
200 | |||||
201 | XS modules: L<JSON::XS>, L<Cpanel::JSON::XS>. | ||||
202 | |||||
203 | =cut | ||||
# spent 8.68ms within JSON::Decode::Regexp::CORE:match which was called 1000 times, avg 9µs/call:
# 1000 times (8.68ms+0s) by JSON::Decode::Regexp::from_json at line 147, avg 9µs/call | |||||
# spent 9µs within JSON::Decode::Regexp::CORE:qr which was called:
# once (9µs+0s) by main::BEGIN@0 at line 142 | |||||
# spent 91.2ms within JSON::Decode::Regexp::CORE:regcomp which was called 1000 times, avg 91µs/call:
# 1000 times (91.2ms+0s) by JSON::Decode::Regexp::from_json at line 147, avg 91µs/call |