← Index
NYTProf Performance Profile   « line view »
For ../prof.pl
  Run on Wed Dec 14 16:10:05 2022
Reported on Wed Dec 14 16:12:58 2022

Filename/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/JSON/Schema/Modern/Vocabulary/Unevaluated.pm
StatementsExecuted 129570 statements in 133ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
374711121ms532msJSON::Schema::Modern::Vocabulary::Unevaluated::::_eval_keyword_unevaluatedPropertiesJSON::Schema::Modern::Vocabulary::Unevaluated::_eval_keyword_unevaluatedProperties
3747113.48ms3.48msJSON::Schema::Modern::Vocabulary::Unevaluated::::CORE:sortJSON::Schema::Modern::Vocabulary::Unevaluated::CORE:sort (opcode)
156111.41ms6.46msJSON::Schema::Modern::Vocabulary::Unevaluated::::_traverse_keyword_unevaluatedPropertiesJSON::Schema::Modern::Vocabulary::Unevaluated::_traverse_keyword_unevaluatedProperties
11131µs34µsJSON::Schema::Modern::Vocabulary::Applicator::::BEGIN@1.309 JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@1.309
11126µs26µsJSON::Schema::Modern::Vocabulary::Unevaluated::::BEGIN@9JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@9
11117µs632µsJSON::Schema::Modern::Vocabulary::Unevaluated::::BEGIN@11JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@11
11112µs35µsJSON::Schema::Modern::Vocabulary::Unevaluated::::BEGIN@13JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@13
11111µs41µsJSON::Schema::Modern::Vocabulary::Unevaluated::::BEGIN@17JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@17
1119µs19µsJSON::Schema::Modern::Vocabulary::Unevaluated::::BEGIN@14JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@14
2219µs11µsJSON::Schema::Modern::Vocabulary::Unevaluated::::keywordsJSON::Schema::Modern::Vocabulary::Unevaluated::keywords
1118µs295µsJSON::Schema::Modern::Vocabulary::Unevaluated::::BEGIN@19JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@19
1117µs212µsJSON::Schema::Modern::Vocabulary::Unevaluated::::BEGIN@10JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@10
1117µs15µsJSON::Schema::Modern::Vocabulary::Unevaluated::::BEGIN@16JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@16
1116µs31µsJSON::Schema::Modern::Vocabulary::Applicator::::BEGIN@2.310 JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@2.310
1116µs87µsJSON::Schema::Modern::Vocabulary::Unevaluated::::BEGIN@12JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@12
1116µs15µsJSON::Schema::Modern::Vocabulary::Unevaluated::::BEGIN@15JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@15
1115µs63µsJSON::Schema::Modern::Vocabulary::Unevaluated::::BEGIN@18JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@18
2112µs2µsJSON::Schema::Modern::Vocabulary::Unevaluated::::CORE:matchJSON::Schema::Modern::Vocabulary::Unevaluated::CORE:match (opcode)
1112µs2µsJSON::Schema::Modern::Vocabulary::Unevaluated::::vocabularyJSON::Schema::Modern::Vocabulary::Unevaluated::vocabulary
2111µs1µsJSON::Schema::Modern::Vocabulary::Unevaluated::::evaluation_orderJSON::Schema::Modern::Vocabulary::Unevaluated::evaluation_order
0000s0sJSON::Schema::Modern::Vocabulary::Unevaluated::::__ANON__[:127]JSON::Schema::Modern::Vocabulary::Unevaluated::__ANON__[:127]
0000s0sJSON::Schema::Modern::Vocabulary::Unevaluated::::__ANON__[:61]JSON::Schema::Modern::Vocabulary::Unevaluated::__ANON__[:61]
0000s0sJSON::Schema::Modern::Vocabulary::Unevaluated::::__ANON__[:77]JSON::Schema::Modern::Vocabulary::Unevaluated::__ANON__[:77]
0000s0sJSON::Schema::Modern::Vocabulary::Unevaluated::::_eval_keyword_unevaluatedItemsJSON::Schema::Modern::Vocabulary::Unevaluated::_eval_keyword_unevaluatedItems
0000s0sJSON::Schema::Modern::Vocabulary::Unevaluated::::_traverse_keyword_unevaluatedItemsJSON::Schema::Modern::Vocabulary::Unevaluated::_traverse_keyword_unevaluatedItems
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1234µs237µs
# spent 34µs (31+3) within JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@1.309 which was called: # once (31µs+3µs) by JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@21 at line 1
use strict;
# spent 34µs making 1 call to JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@1.309 # spent 3µs making 1 call to strict::import
2261µs256µs
# spent 31µs (6+25) within JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@2.310 which was called: # once (6µs+25µs) by JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@21 at line 2
use warnings;
# spent 31µs making 1 call to JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@2.310 # spent 25µs making 1 call to warnings::import
3package JSON::Schema::Modern::Vocabulary::Unevaluated;
4# vim: set ts=8 sts=2 sw=2 tw=100 et :
5# ABSTRACT: Implementation of the JSON Schema Unevaluated vocabulary
6
710sour $VERSION = '0.558';
8
9249µs126µs
# spent 26µs within JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@9 which was called: # once (26µs+0s) by JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@21 at line 9
use 5.020;
10223µs2417µs
# spent 212µs (7+205) within JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@10 which was called: # once (7µs+205µs) by JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@21 at line 10
use Moo;
# spent 212µs making 1 call to JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@10 # spent 205µs making 1 call to Moo::import
11323µs31.25ms
# spent 632µs (17+615) within JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@11 which was called: # once (17µs+615µs) by JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@21 at line 11
use strictures 2;
# spent 632µs making 1 call to JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@11 # spent 599µs making 1 call to strictures::import # spent 16µs making 1 call to strictures::VERSION
12227µs2168µs
# spent 87µs (6+81) within JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@12 which was called: # once (6µs+81µs) by JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@21 at line 12
use experimental qw(signatures postderef);
# spent 87µs making 1 call to JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@12 # spent 81µs making 1 call to experimental::import
13222µs238µs
# spent 35µs (12+23) within JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@13 which was called: # once (12µs+23µs) by JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@21 at line 13
use if "$]" >= 5.022, experimental => 're_strict';
# spent 35µs making 1 call to JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@13 # spent 3µs making 1 call to if::import
14218µs220µs
# spent 19µs (9+10) within JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@14 which was called: # once (9µs+10µs) by JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@21 at line 14
no if "$]" >= 5.031009, feature => 'indirect';
# spent 19µs making 1 call to JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@14 # spent 1µs making 1 call to if::unimport
15214µs217µs
# spent 15µs (6+9) within JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@15 which was called: # once (6µs+9µs) by JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@21 at line 15
no if "$]" >= 5.033001, feature => 'multidimensional';
# spent 15µs making 1 call to JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@15 # spent 2µs making 1 call to if::unimport
16218µs216µs
# spent 15µs (7+8) within JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@16 which was called: # once (7µs+8µs) by JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@21 at line 16
no if "$]" >= 5.033006, feature => 'bareword_filehandles';
# spent 15µs making 1 call to JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@16 # spent 1µs making 1 call to if::unimport
17325µs352µs
# spent 41µs (11+30) within JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@17 which was called: # once (11µs+30µs) by JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@21 at line 17
use List::Util 1.45 qw(any max);
# spent 41µs making 1 call to JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@17 # spent 7µs making 1 call to List::Util::import # spent 4µs making 1 call to UNIVERSAL::VERSION
18214µs2121µs
# spent 63µs (5+58) within JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@18 which was called: # once (5µs+58µs) by JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@21 at line 18
use JSON::Schema::Modern::Utilities qw(is_type jsonp local_annotations E A abort true);
# spent 63µs making 1 call to JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@18 # spent 58µs making 1 call to Exporter::import
1921.45ms2582µs
# spent 295µs (8+287) within JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@19 which was called: # once (8µs+287µs) by JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@21 at line 19
use namespace::clean;
# spent 295µs making 1 call to JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@19 # spent 287µs making 1 call to namespace::clean::import
20
2112µs1495µswith 'JSON::Schema::Modern::Vocabulary';
# spent 495µs making 1 call to Moo::with
22
23
# spent 2µs within JSON::Schema::Modern::Vocabulary::Unevaluated::vocabulary which was called: # once (2µs+0s) by JSON::Schema::Modern::__ANON__[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/JSON/Schema/Modern.pm:700] at line 696 of JSON/Schema/Modern.pm
sub vocabulary {
2413µs 'https://json-schema.org/draft/2020-12/vocab/unevaluated' => 'draft2020-12';
25}
26
2722µs
# spent 1µs within JSON::Schema::Modern::Vocabulary::Unevaluated::evaluation_order which was called 2 times, avg 500ns/call: # 2 times (1µs+0s) by JSON::Schema::Modern::Vocabulary::Core::CORE:sort at line 331 of JSON/Schema/Modern/Vocabulary/Core.pm, avg 500ns/call
sub evaluation_order { 7 }
28
29# This vocabulary should be evaluated after the Applicator vocabulary.
3061µs
# spent 11µs (9+2) within JSON::Schema::Modern::Vocabulary::Unevaluated::keywords which was called 2 times, avg 6µs/call: # once (5µs+1000ns) by JSON::Schema::Modern::_eval_subschema at line 563 of JSON/Schema/Modern.pm # once (4µs+1µs) by JSON::Schema::Modern::_traverse_subschema at line 475 of JSON/Schema/Modern.pm
sub keywords ($self, $spec_version) {
3127µs22µs die 'Unevaluated not implemented in '.$spec_version if $spec_version =~ /^draft[467]$/;
# spent 2µs making 2 calls to JSON::Schema::Modern::Vocabulary::Unevaluated::CORE:match, avg 1µs/call
3224µs qw(unevaluatedItems unevaluatedProperties);
33}
34
35sub _traverse_keyword_unevaluatedItems ($self, $schema, $state) {
36 my $valid = $self->traverse_subschema($schema, $state);
37
38 # remember that annotations need to be collected in order to evaluate this keyword
39 $state->{configs}{collect_annotations} = 1;
40
41 return $valid;
42}
43
44sub _eval_keyword_unevaluatedItems ($self, $data, $schema, $state) {
45 abort($state, 'EXCEPTION: "unevaluatedItems" keyword present, but annotation collection is disabled')
46 if not $state->{collect_annotations};
47
48 abort($state, 'EXCEPTION: "unevaluatedItems" keyword present, but short_circuit is enabled: results unreliable')
49 if $state->{short_circuit};
50
51 return 1 if not is_type('array', $data);
52
53 my @annotations = local_annotations($state);
54
55 # a relevant keyword already produced a 'true' annotation at this location
56 my @boolean_annotation_keywords =
57 $state->{spec_version} eq 'draft2019-09' ? qw(items additionalItems unevaluatedItems)
58 : qw(prefixItems items contains unevaluatedItems);
59 my %bools; @bools{@boolean_annotation_keywords} = (1)x@boolean_annotation_keywords;
60 return 1
61 if any { $bools{$_->{keyword}} && is_type('boolean', $_->{annotation}) && $_->{annotation} }
62 @annotations;
63
64 # otherwise, evaluate at every instance item greater than the max of all 'prefixItems'/numeric
65 # 'items' annotations that isn't in a 'contains' annotation
66 my $max_index_annotation_keyword = $state->{spec_version} eq 'draft2019-09' ? 'items' : 'prefixItems';
67 my $last_index = max(-1, grep is_type('integer', $_),
68 map +($_->{keyword} eq $max_index_annotation_keyword ? $_->{annotation} : ()), @annotations);
69
70 return 1 if $last_index == $data->$#*;
71
72 my @contains_annotation_indexes = $state->{spec_version} eq 'draft2019-09' ? ()
73 : map +($_->{keyword} eq 'contains' ? $_->{annotation}->@* : ()), @annotations;
74
75 my $valid = 1;
76 foreach my $idx ($last_index+1 .. $data->$#*) {
77 next if any { $idx == $_ } @contains_annotation_indexes;
78 if (is_type('boolean', $schema->{unevaluatedItems})) {
79 next if $schema->{unevaluatedItems};
80 $valid = E({ %$state, data_path => $state->{data_path}.'/'.$idx },
81 'additional item not permitted')
82 }
83 else {
84 if ($self->eval($data->[$idx], $schema->{unevaluatedItems},
85 +{ %$state, data_path => $state->{data_path}.'/'.$idx,
86 schema_path => $state->{schema_path}.'/unevaluatedItems' })) {
87 next;
88 }
89
90 $valid = 0;
91 }
92 last if $state->{short_circuit};
93 }
94
95 A($state, true);
96 return E($state, 'subschema is not valid against all additional items') if not $valid;
97 return 1;
98}
99
100624120µs
# spent 6.46ms (1.41+5.05) within JSON::Schema::Modern::Vocabulary::Unevaluated::_traverse_keyword_unevaluatedProperties which was called 156 times, avg 41µs/call: # 156 times (1.41ms+5.05ms) by JSON::Schema::Modern::_traverse_subschema at line 487 of JSON/Schema/Modern.pm, avg 41µs/call
sub _traverse_keyword_unevaluatedProperties ($self, $schema, $state) {
101156655µs1563.72ms my $valid = $self->traverse_subschema($schema, $state);
# spent 5.05ms making 156 calls to JSON::Schema::Modern::Vocabulary::traverse_subschema, avg 32µs/call, recursion: max depth 2, sum of overlapping time 1.33ms
102
103 # remember that annotations need to be collected in order to evaluate this keyword
104156134µs $state->{configs}{collect_annotations} = 1;
105
106156304µs return $valid;
107}
108
109187354.48ms
# spent 532ms (121+411) within JSON::Schema::Modern::Vocabulary::Unevaluated::_eval_keyword_unevaluatedProperties which was called 3747 times, avg 142µs/call: # 3747 times (121ms+411ms) by JSON::Schema::Modern::_eval_subschema at line 578 of JSON/Schema/Modern.pm, avg 142µs/call
sub _eval_keyword_unevaluatedProperties ($self, $data, $schema, $state) {
110 abort($state, 'EXCEPTION: "unevaluatedProperties" keyword present, but annotation collection is disabled')
11137471.85ms if not $state->{collect_annotations};
112
113 abort($state, 'EXCEPTION: "unevaluatedProperties" keyword present, but short_circuit is enabled: results unreliable')
11437471.87ms if $state->{short_circuit};
115
11637475.43ms37478.57ms return 1 if not is_type('object', $data);
# spent 8.57ms making 3747 calls to JSON::Schema::Modern::Utilities::is_type, avg 2µs/call
117
118 my @evaluated_properties = map {
1191274515.2ms3747143ms my $keyword = $_->{keyword};
# spent 143ms making 3747 calls to JSON::Schema::Modern::Utilities::local_annotations, avg 38µs/call
120 (grep $keyword eq $_, qw(properties additionalProperties patternProperties unevaluatedProperties))
121899811.6ms ? $_->{annotation}->@* : ();
122 } local_annotations($state);
123
1243747753µs my $valid = 1;
1253747804µs my @properties;
126374723.8ms37473.48ms foreach my $property (sort keys %$data) {
# spent 3.48ms making 3747 calls to JSON::Schema::Modern::Vocabulary::Unevaluated::CORE:sort, avg 929ns/call
1275423348.3ms799118.9ms next if any { $_ eq $property } @evaluated_properties;
# spent 18.9ms making 7991 calls to List::Util::any, avg 2µs/call
128 push @properties, $property;
129
130 if (is_type('boolean', $schema->{unevaluatedProperties})) {
131 next if $schema->{unevaluatedProperties};
132 $valid = E({ %$state, data_path => jsonp($state->{data_path}, $property) },
133 'additional property not permitted');
134 }
135 else {
136 if ($self->eval($data->{$property}, $schema->{unevaluatedProperties},
137 +{ %$state, data_path => jsonp($state->{data_path}, $property),
138 schema_path => $state->{schema_path}.'/unevaluatedProperties' })) {
139 next;
140 }
141
142 $valid = 0;
143 }
144 last if $state->{short_circuit};
145 }
146
14737474.65ms3747237ms A($state, \@properties);
# spent 237ms making 3747 calls to JSON::Schema::Modern::Utilities::A, avg 63µs/call
14837471.05ms return E($state, 'not all additional properties are valid') if not $valid;
149374710.6ms return 1;
150}
151
15216µs1;
153
154125µs1479µs__END__
 
# spent 2µs within JSON::Schema::Modern::Vocabulary::Unevaluated::CORE:match which was called 2 times, avg 1µs/call: # 2 times (2µs+0s) by JSON::Schema::Modern::Vocabulary::Unevaluated::keywords at line 31, avg 1µs/call
sub JSON::Schema::Modern::Vocabulary::Unevaluated::CORE:match; # opcode
# spent 3.48ms within JSON::Schema::Modern::Vocabulary::Unevaluated::CORE:sort which was called 3747 times, avg 929ns/call: # 3747 times (3.48ms+0s) by JSON::Schema::Modern::Vocabulary::Unevaluated::_eval_keyword_unevaluatedProperties at line 126, avg 929ns/call
sub JSON::Schema::Modern::Vocabulary::Unevaluated::CORE:sort; # opcode