| 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 | JSON::Decode::Regexp::CORE:regcomp (opcode) |
| 1000 | 1 | 1 | 9.39ms | 109ms | JSON::Decode::Regexp::from_json |
| 1000 | 1 | 1 | 8.68ms | 8.68ms | JSON::Decode::Regexp::CORE:match (opcode) |
| 1 | 1 | 1 | 2.52ms | 2.57ms | JSON::Decode::Regexp::BEGIN@8 |
| 1 | 1 | 1 | 616µs | 701µs | JSON::Decode::Regexp::BEGIN@7 |
| 1 | 1 | 1 | 28µs | 28µs | JSON::Decode::Regexp::BEGIN@6 |
| 1 | 1 | 1 | 9µs | 9µs | JSON::Decode::Regexp::CORE:qr (opcode) |
| 0 | 0 | 0 | 0s | 0s | JSON::Decode::Regexp::__ANON__[lib/JSON/Decode/Regexp.pm:142] |
| 0 | 0 | 0 | 0s | 0s | JSON::Decode::Regexp::_fail |
| 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 |