← Index
NYTProf Performance Profile   « line view »
For ../prof.pl
  Run on Wed Dec 14 15:33:55 2022
Reported on Wed Dec 14 15:40:04 2022

Filename/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/JSON/Schema/Modern/Vocabulary/Unevaluated.pm
StatementsExecuted 607923 statements in 596ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
9407521264ms342msJSON::Schema::Modern::Vocabulary::Unevaluated::::keywordsJSON::Schema::Modern::Vocabulary::Unevaluated::keywords
374711177ms1.99sJSON::Schema::Modern::Vocabulary::Unevaluated::::_eval_keyword_unevaluatedPropertiesJSON::Schema::Modern::Vocabulary::Unevaluated::_eval_keyword_unevaluatedProperties
940751177.3ms77.3msJSON::Schema::Modern::Vocabulary::Unevaluated::::CORE:matchJSON::Schema::Modern::Vocabulary::Unevaluated::CORE:match (opcode)
3747114.20ms4.20msJSON::Schema::Modern::Vocabulary::Unevaluated::::CORE:sortJSON::Schema::Modern::Vocabulary::Unevaluated::CORE:sort (opcode)
156111.09ms5.62msJSON::Schema::Modern::Vocabulary::Unevaluated::::_traverse_keyword_unevaluatedPropertiesJSON::Schema::Modern::Vocabulary::Unevaluated::_traverse_keyword_unevaluatedProperties
11125µs28µsJSON::Schema::Modern::Vocabulary::Applicator::::BEGIN@1.308 JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@1.308
11116µs48µsJSON::Schema::Modern::Vocabulary::Unevaluated::::BEGIN@17JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@17
11114µs570µsJSON::Schema::Modern::Vocabulary::Unevaluated::::BEGIN@11JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@11
11113µs34µsJSON::Schema::Modern::Vocabulary::Unevaluated::::BEGIN@13JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@13
11110µs18µsJSON::Schema::Modern::Vocabulary::Unevaluated::::BEGIN@16JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@16
11110µs10µsJSON::Schema::Modern::Vocabulary::Unevaluated::::BEGIN@9JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@9
1119µs23µsJSON::Schema::Modern::Vocabulary::Unevaluated::::BEGIN@14JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@14
1117µs35µsJSON::Schema::Modern::Vocabulary::Applicator::::BEGIN@2.309 JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@2.309
1117µs366µsJSON::Schema::Modern::Vocabulary::Unevaluated::::BEGIN@19JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@19
1116µs202µsJSON::Schema::Modern::Vocabulary::Unevaluated::::BEGIN@10JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@10
1116µs12µsJSON::Schema::Modern::Vocabulary::Unevaluated::::BEGIN@15JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@15
1115µs80µsJSON::Schema::Modern::Vocabulary::Unevaluated::::BEGIN@12JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@12
1113µs26µsJSON::Schema::Modern::Vocabulary::Unevaluated::::BEGIN@18JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@18
2112µs2µsJSON::Schema::Modern::Vocabulary::Unevaluated::::evaluation_orderJSON::Schema::Modern::Vocabulary::Unevaluated::evaluation_order
1112µs2µsJSON::Schema::Modern::Vocabulary::Unevaluated::::vocabularyJSON::Schema::Modern::Vocabulary::Unevaluated::vocabulary
0000s0sJSON::Schema::Modern::Vocabulary::Unevaluated::::__ANON__[:134]JSON::Schema::Modern::Vocabulary::Unevaluated::__ANON__[:134]
0000s0sJSON::Schema::Modern::Vocabulary::Unevaluated::::__ANON__[:61]JSON::Schema::Modern::Vocabulary::Unevaluated::__ANON__[:61]
0000s0sJSON::Schema::Modern::Vocabulary::Unevaluated::::__ANON__[:79]JSON::Schema::Modern::Vocabulary::Unevaluated::__ANON__[:79]
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
1227µs231µs
# spent 28µs (25+3) within JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@1.308 which was called: # once (25µs+3µs) by JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@21 at line 1
use strict;
# spent 28µs making 1 call to JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@1.308 # spent 3µs making 1 call to strict::import
2236µs263µs
# spent 35µs (7+28) within JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@2.309 which was called: # once (7µs+28µs) by JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@21 at line 2
use warnings;
# spent 35µs making 1 call to JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@2.309 # spent 28µ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.552';
8
9238µs110µs
# spent 10µs within JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@9 which was called: # once (10µs+0s) by JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@21 at line 9
use 5.020;
10221µs2398µs
# spent 202µs (6+196) within JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@10 which was called: # once (6µs+196µs) by JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@21 at line 10
use Moo;
# spent 202µs making 1 call to JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@10 # spent 196µs making 1 call to Moo::import
11331µs31.13ms
# spent 570µs (14+556) within JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@11 which was called: # once (14µs+556µs) by JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@21 at line 11
use strictures 2;
# spent 570µs making 1 call to JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@11 # spent 541µs making 1 call to strictures::import # spent 15µs making 1 call to strictures::VERSION
12227µs2155µs
# spent 80µs (5+75) within JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@12 which was called: # once (5µs+75µs) by JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@21 at line 12
use experimental qw(signatures postderef);
# spent 80µs making 1 call to JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@12 # spent 75µs making 1 call to experimental::import
13226µs237µs
# spent 34µs (13+21) within JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@13 which was called: # once (13µs+21µs) by JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@21 at line 13
use if "$]" >= 5.022, experimental => 're_strict';
# spent 34µs making 1 call to JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@13 # spent 3µs making 1 call to if::import
14216µs223µs
# spent 23µs (9+14) within JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@14 which was called: # once (9µs+14µs) by JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@21 at line 14
no if "$]" >= 5.031009, feature => 'indirect';
# spent 23µs making 1 call to JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@14 # spent 0s making 1 call to if::unimport
15215µs212µs
# spent 12µs (6+6) within JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@15 which was called: # once (6µs+6µs) by JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@21 at line 15
no if "$]" >= 5.033001, feature => 'multidimensional';
# spent 12µs making 1 call to JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@15 # spent 0s making 1 call to if::unimport
16219µs219µs
# spent 18µs (10+8) within JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@16 which was called: # once (10µs+8µs) by JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@21 at line 16
no if "$]" >= 5.033006, feature => 'bareword_filehandles';
# spent 18µs making 1 call to JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@16 # spent 1µs making 1 call to if::unimport
17331µs361µs
# spent 48µs (16+32) within JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@17 which was called: # once (16µs+32µs) by JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@21 at line 17
use List::Util 1.45 qw(any max);
# spent 48µs making 1 call to JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@17 # spent 9µs making 1 call to List::Util::import # spent 4µs making 1 call to UNIVERSAL::VERSION
18214µs249µs
# spent 26µs (3+23) within JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@18 which was called: # once (3µs+23µ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 26µs making 1 call to JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@18 # spent 23µs making 1 call to Exporter::import
1921.42ms2725µs
# spent 366µs (7+359) within JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@19 which was called: # once (7µs+359µs) by JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@21 at line 19
use namespace::clean;
# spent 366µs making 1 call to JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@19 # spent 359µs making 1 call to namespace::clean::import
20
2111µs1511µswith 'JSON::Schema::Modern::Vocabulary';
# spent 511µ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:670] at line 666 of JSON/Schema/Modern.pm
sub vocabulary {
2413µs 'https://json-schema.org/draft/2020-12/vocab/unevaluated' => 'draft2020-12';
25}
26
2724µs
# spent 2µs within JSON::Schema::Modern::Vocabulary::Unevaluated::evaluation_order which was called 2 times, avg 1µs/call: # 2 times (2µs+0s) by JSON::Schema::Modern::Vocabulary::Core::CORE:sort at line 322 of JSON/Schema/Modern/Vocabulary/Core.pm, avg 1µs/call
sub evaluation_order { 7 }
28
29# This vocabulary should be evaluated after the Applicator vocabulary.
3028222541.0ms
# spent 342ms (264+77.3) within JSON::Schema::Modern::Vocabulary::Unevaluated::keywords which was called 94075 times, avg 4µs/call: # 91595 times (258ms+75.4ms) by JSON::Schema::Modern::_eval_subschema at line 535 of JSON/Schema/Modern.pm, avg 4µs/call # 2480 times (6.68ms+1.91ms) by JSON::Schema::Modern::_traverse_subschema at line 447 of JSON/Schema/Modern.pm, avg 3µs/call
sub keywords ($self, $spec_version) {
3194075205ms9407577.3ms die 'Unevaluated not implemented in '.$spec_version if $spec_version =~ /^draft[467]$/;
# spent 77.3ms making 94075 calls to JSON::Schema::Modern::Vocabulary::Unevaluated::CORE:match, avg 822ns/call
3294075167ms 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 my @orig_annotations = $state->{annotations}->@*;
77 my @new_annotations;
78 foreach my $idx ($last_index+1 .. $data->$#*) {
79 next if any { $idx == $_ } @contains_annotation_indexes;
80 if (is_type('boolean', $schema->{unevaluatedItems})) {
81 next if $schema->{unevaluatedItems};
82 $valid = E({ %$state, data_path => $state->{data_path}.'/'.$idx },
83 'additional item not permitted')
84 }
85 else {
86 my @annotations = @orig_annotations;
87 if ($self->eval($data->[$idx], $schema->{unevaluatedItems},
88 +{ %$state, annotations => \@annotations,
89 data_path => $state->{data_path}.'/'.$idx,
90 schema_path => $state->{schema_path}.'/unevaluatedItems' })) {
91 push @new_annotations, @annotations[$#orig_annotations+1 .. $#annotations];
92 next;
93 }
94
95 $valid = 0;
96 }
97 last if $state->{short_circuit};
98 }
99
100 push $state->{annotations}->@*, @new_annotations;
101 A($state, true);
102 return E($state, 'subschema is not valid against all additional items') if not $valid;
103 return 1;
104}
105
106624154µs
# spent 5.62ms (1.09+4.52) within JSON::Schema::Modern::Vocabulary::Unevaluated::_traverse_keyword_unevaluatedProperties which was called 156 times, avg 36µs/call: # 156 times (1.09ms+4.52ms) by JSON::Schema::Modern::_traverse_subschema at line 457 of JSON/Schema/Modern.pm, avg 36µs/call
sub _traverse_keyword_unevaluatedProperties ($self, $schema, $state) {
107156486µs1563.30ms my $valid = $self->traverse_subschema($schema, $state);
# spent 4.52ms making 156 calls to JSON::Schema::Modern::Vocabulary::traverse_subschema, avg 29µs/call, recursion: max depth 2, sum of overlapping time 1.22ms
108
109 # remember that annotations need to be collected in order to evaluate this keyword
110156132µs $state->{configs}{collect_annotations} = 1;
111
112156352µs return $valid;
113}
114
115187353.80ms
# spent 1.99s (177ms+1.81) within JSON::Schema::Modern::Vocabulary::Unevaluated::_eval_keyword_unevaluatedProperties which was called 3747 times, avg 531µs/call: # 3747 times (177ms+1.81s) by JSON::Schema::Modern::_eval_subschema at line 548 of JSON/Schema/Modern.pm, avg 531µs/call
sub _eval_keyword_unevaluatedProperties ($self, $data, $schema, $state) {
116 abort($state, 'EXCEPTION: "unevaluatedProperties" keyword present, but annotation collection is disabled')
11737472.46ms if not $state->{collect_annotations};
118
119 abort($state, 'EXCEPTION: "unevaluatedProperties" keyword present, but short_circuit is enabled: results unreliable')
12037471.87ms if $state->{short_circuit};
121
12237475.09ms37477.72ms return 1 if not is_type('object', $data);
# spent 7.72ms making 3747 calls to JSON::Schema::Modern::Utilities::is_type, avg 2µs/call
123
124 my @evaluated_properties = map {
1251299223.0ms12992817ms my $keyword = $_->keyword;
# spent 805ms making 3747 calls to JSON::Schema::Modern::Utilities::local_annotations, avg 215µs/call # spent 11.9ms making 9245 calls to JSON::Schema::Modern::Annotation::keyword, avg 1µs/call
126924521.3ms924410.8ms (grep $keyword eq $_, qw(properties additionalProperties patternProperties unevaluatedProperties))
# spent 10.8ms making 9244 calls to JSON::Schema::Modern::Annotation::annotation, avg 1µs/call
127 ? $_->annotation->@* : ();
128 } local_annotations($state);
129
13037471.13ms my $valid = 1;
131374717.9ms my @orig_annotations = $state->{annotations}->@*;
13237471.23ms my (@properties, @new_annotations);
133374722.1ms37474.20ms foreach my $property (sort keys %$data) {
# spent 4.20ms making 3747 calls to JSON::Schema::Modern::Vocabulary::Unevaluated::CORE:sort, avg 1µs/call
1345423346.4ms799118.3ms next if any { $_ eq $property } @evaluated_properties;
# spent 18.3ms making 7991 calls to List::Util::any, avg 2µs/call
135 push @properties, $property;
136
137 if (is_type('boolean', $schema->{unevaluatedProperties})) {
138 next if $schema->{unevaluatedProperties};
139 $valid = E({ %$state, data_path => jsonp($state->{data_path}, $property) },
140 'additional property not permitted');
141 }
142 else {
143 my @annotations = @orig_annotations;
144 if ($self->eval($data->{$property}, $schema->{unevaluatedProperties},
145 +{ %$state, annotations => \@annotations,
146 data_path => jsonp($state->{data_path}, $property),
147 schema_path => $state->{schema_path}.'/unevaluatedProperties' })) {
148 push @new_annotations, @annotations[$#orig_annotations+1 .. $#annotations];
149 next;
150 }
151
152 $valid = 0;
153 }
154 last if $state->{short_circuit};
155 }
156
15737472.25ms push $state->{annotations}->@*, @new_annotations;
15837475.50ms3747954ms A($state, \@properties);
# spent 954ms making 3747 calls to JSON::Schema::Modern::Utilities::A, avg 255µs/call
15937471.91ms return E($state, 'not all additional properties are valid') if not $valid;
160374724.0ms return 1;
161}
162
16315µs1;
164
165124µs1456µs__END__
 
# spent 77.3ms within JSON::Schema::Modern::Vocabulary::Unevaluated::CORE:match which was called 94075 times, avg 822ns/call: # 94075 times (77.3ms+0s) by JSON::Schema::Modern::Vocabulary::Unevaluated::keywords at line 31, avg 822ns/call
sub JSON::Schema::Modern::Vocabulary::Unevaluated::CORE:match; # opcode
# spent 4.20ms within JSON::Schema::Modern::Vocabulary::Unevaluated::CORE:sort which was called 3747 times, avg 1µs/call: # 3747 times (4.20ms+0s) by JSON::Schema::Modern::Vocabulary::Unevaluated::_eval_keyword_unevaluatedProperties at line 133, avg 1µs/call
sub JSON::Schema::Modern::Vocabulary::Unevaluated::CORE:sort; # opcode