← Index
NYTProf Performance Profile   « line view »
For ../prof.pl
  Run on Wed Dec 14 15:57:08 2022
Reported on Wed Dec 14 16:00:37 2022

Filename/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/JSON/Schema/Modern/Vocabulary/Unevaluated.pm
StatementsExecuted 129570 statements in 149ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
374711147ms2.07sJSON::Schema::Modern::Vocabulary::Unevaluated::::_eval_keyword_unevaluatedPropertiesJSON::Schema::Modern::Vocabulary::Unevaluated::_eval_keyword_unevaluatedProperties
3747114.03ms4.03msJSON::Schema::Modern::Vocabulary::Unevaluated::::CORE:sortJSON::Schema::Modern::Vocabulary::Unevaluated::CORE:sort (opcode)
156111.72ms7.75msJSON::Schema::Modern::Vocabulary::Unevaluated::::_traverse_keyword_unevaluatedPropertiesJSON::Schema::Modern::Vocabulary::Unevaluated::_traverse_keyword_unevaluatedProperties
11130µs34µsJSON::Schema::Modern::Vocabulary::Applicator::::BEGIN@1.308 JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@1.308
22119µs24µsJSON::Schema::Modern::Vocabulary::Unevaluated::::keywordsJSON::Schema::Modern::Vocabulary::Unevaluated::keywords
11113µs34µsJSON::Schema::Modern::Vocabulary::Unevaluated::::BEGIN@13JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@13
11113µs67µsJSON::Schema::Modern::Vocabulary::Unevaluated::::BEGIN@17JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@17
11112µs670µsJSON::Schema::Modern::Vocabulary::Unevaluated::::BEGIN@11JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@11
11110µs199µsJSON::Schema::Modern::Vocabulary::Unevaluated::::BEGIN@10JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@10
11110µs24µsJSON::Schema::Modern::Vocabulary::Unevaluated::::BEGIN@14JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@14
11110µs10µsJSON::Schema::Modern::Vocabulary::Unevaluated::::BEGIN@9JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@9
1119µs16µsJSON::Schema::Modern::Vocabulary::Unevaluated::::BEGIN@16JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@16
1117µs37µsJSON::Schema::Modern::Vocabulary::Applicator::::BEGIN@2.309 JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@2.309
1117µs108µsJSON::Schema::Modern::Vocabulary::Unevaluated::::BEGIN@12JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@12
1117µs18µsJSON::Schema::Modern::Vocabulary::Unevaluated::::BEGIN@15JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@15
1117µs32µsJSON::Schema::Modern::Vocabulary::Unevaluated::::BEGIN@18JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@18
1116µs193µsJSON::Schema::Modern::Vocabulary::Unevaluated::::BEGIN@19JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@19
2115µs5µ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
1230µs238µs
# spent 34µs (30+4) within JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@1.308 which was called: # once (30µs+4µ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.308 # spent 4µs making 1 call to strict::import
2237µs267µs
# spent 37µs (7+30) within JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@2.309 which was called: # once (7µs+30µs) by JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@21 at line 2
use warnings;
# spent 37µs making 1 call to JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@2.309 # spent 30µ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.556';
8
9232µ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;
10226µs2388µs
# spent 199µs (10+189) within JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@10 which was called: # once (10µs+189µs) by JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@21 at line 10
use Moo;
# spent 199µs making 1 call to JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@10 # spent 189µs making 1 call to Moo::import
11339µs31.33ms
# spent 670µs (12+658) within JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@11 which was called: # once (12µs+658µs) by JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@21 at line 11
use strictures 2;
# spent 670µs making 1 call to JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@11 # spent 641µs making 1 call to strictures::import # spent 16µs making 1 call to strictures::VERSION
12238µs2209µs
# spent 108µs (7+101) within JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@12 which was called: # once (7µs+101µs) by JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@21 at line 12
use experimental qw(signatures postderef);
# spent 108µs making 1 call to JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@12 # spent 101µs making 1 call to experimental::import
13223µs235µ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 1µs making 1 call to if::import
14222µs225µs
# spent 24µs (10+14) within JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@14 which was called: # once (10µs+14µs) by JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@21 at line 14
no if "$]" >= 5.031009, feature => 'indirect';
# spent 24µs making 1 call to JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@14 # spent 1µs making 1 call to if::unimport
15221µs220µs
# spent 18µs (7+11) within JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@15 which was called: # once (7µs+11µs) by JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@21 at line 15
no if "$]" >= 5.033001, feature => 'multidimensional';
# spent 18µs making 1 call to JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@15 # spent 2µs making 1 call to if::unimport
16219µs218µs
# spent 16µs (9+7) within JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@16 which was called: # once (9µs+7µs) by JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@21 at line 16
no if "$]" >= 5.033006, feature => 'bareword_filehandles';
# spent 16µs making 1 call to JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@16 # spent 2µs making 1 call to if::unimport
17335µs390µs
# spent 67µs (13+54) within JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@17 which was called: # once (13µs+54µs) by JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@21 at line 17
use List::Util 1.45 qw(any max);
# spent 67µs making 1 call to JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@17 # spent 14µs making 1 call to List::Util::import # spent 9µs making 1 call to UNIVERSAL::VERSION
18216µs257µs
# spent 32µs (7+25) within JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@18 which was called: # once (7µs+25µ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 32µs making 1 call to JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@18 # spent 25µs making 1 call to Exporter::import
1921.21ms2380µs
# spent 193µs (6+187) within JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@19 which was called: # once (6µs+187µs) by JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@21 at line 19
use namespace::clean;
# spent 193µs making 1 call to JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@19 # spent 187µs making 1 call to namespace::clean::import
20
2112µs1798µswith 'JSON::Schema::Modern::Vocabulary';
# spent 798µ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:696] at line 692 of JSON/Schema/Modern.pm
sub vocabulary {
2413µs 'https://json-schema.org/draft/2020-12/vocab/unevaluated' => 'draft2020-12';
25}
26
2727µ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 24µs (19+5) within JSON::Schema::Modern::Vocabulary::Unevaluated::keywords which was called 2 times, avg 12µs/call: # once (14µs+1µs) by JSON::Schema::Modern::_traverse_subschema at line 471 of JSON/Schema/Modern.pm # once (5µs+4µs) by JSON::Schema::Modern::_eval_subschema at line 559 of JSON/Schema/Modern.pm
sub keywords ($self, $spec_version) {
31219µs25µs die 'Unevaluated not implemented in '.$spec_version if $spec_version =~ /^draft[467]$/;
# spent 5µs making 2 calls to JSON::Schema::Modern::Vocabulary::Unevaluated::CORE:match, avg 2µs/call
3228µ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
100624160µs
# spent 7.75ms (1.72+6.02) within JSON::Schema::Modern::Vocabulary::Unevaluated::_traverse_keyword_unevaluatedProperties which was called 156 times, avg 50µs/call: # 156 times (1.72ms+6.02ms) by JSON::Schema::Modern::_traverse_subschema at line 483 of JSON/Schema/Modern.pm, avg 50µs/call
sub _traverse_keyword_unevaluatedProperties ($self, $schema, $state) {
101156752µs1564.50ms my $valid = $self->traverse_subschema($schema, $state);
# spent 6.02ms making 156 calls to JSON::Schema::Modern::Vocabulary::traverse_subschema, avg 39µs/call, recursion: max depth 2, sum of overlapping time 1.52ms
102
103 # remember that annotations need to be collected in order to evaluate this keyword
104156206µs $state->{configs}{collect_annotations} = 1;
105
106156385µs return $valid;
107}
108
109187354.43ms
# spent 2.07s (147ms+1.92) within JSON::Schema::Modern::Vocabulary::Unevaluated::_eval_keyword_unevaluatedProperties which was called 3747 times, avg 552µs/call: # 3747 times (147ms+1.92s) by JSON::Schema::Modern::_eval_subschema at line 574 of JSON/Schema/Modern.pm, avg 552µs/call
sub _eval_keyword_unevaluatedProperties ($self, $data, $schema, $state) {
110 abort($state, 'EXCEPTION: "unevaluatedProperties" keyword present, but annotation collection is disabled')
11137471.64ms if not $state->{collect_annotations};
112
113 abort($state, 'EXCEPTION: "unevaluatedProperties" keyword present, but short_circuit is enabled: results unreliable')
11437471.75ms if $state->{short_circuit};
115
11637475.32ms37478.81ms return 1 if not is_type('object', $data);
# spent 8.81ms making 3747 calls to JSON::Schema::Modern::Utilities::is_type, avg 2µs/call
117
118 my @evaluated_properties = map {
1191274521.2ms12745896ms my $keyword = $_->keyword;
# spent 886ms making 3747 calls to JSON::Schema::Modern::Utilities::local_annotations, avg 236µs/call # spent 10.4ms making 8998 calls to JSON::Schema::Modern::Annotation::keyword, avg 1µs/call
120899819.2ms899710.5ms (grep $keyword eq $_, qw(properties additionalProperties patternProperties unevaluatedProperties))
# spent 10.5ms making 8997 calls to JSON::Schema::Modern::Annotation::annotation, avg 1µs/call
121 ? $_->annotation->@* : ();
122 } local_annotations($state);
123
1243747798µs my $valid = 1;
1253747695µs my @properties;
126374722.0ms37474.03ms foreach my $property (sort keys %$data) {
# spent 4.03ms making 3747 calls to JSON::Schema::Modern::Vocabulary::Unevaluated::CORE:sort, avg 1µs/call
1275423351.8ms799118.5ms next if any { $_ eq $property } @evaluated_properties;
# spent 18.5ms 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.56ms3747982ms A($state, \@properties);
# spent 982ms making 3747 calls to JSON::Schema::Modern::Utilities::A, avg 262µs/call
1483747927µs return E($state, 'not all additional properties are valid') if not $valid;
149374711.4ms return 1;
150}
151
15217µs1;
153
154133µs1502µs__END__
 
# spent 5µs within JSON::Schema::Modern::Vocabulary::Unevaluated::CORE:match which was called 2 times, avg 2µs/call: # 2 times (5µs+0s) by JSON::Schema::Modern::Vocabulary::Unevaluated::keywords at line 31, avg 2µs/call
sub JSON::Schema::Modern::Vocabulary::Unevaluated::CORE:match; # opcode
# spent 4.03ms within JSON::Schema::Modern::Vocabulary::Unevaluated::CORE:sort which was called 3747 times, avg 1µs/call: # 3747 times (4.03ms+0s) by JSON::Schema::Modern::Vocabulary::Unevaluated::_eval_keyword_unevaluatedProperties at line 126, avg 1µs/call
sub JSON::Schema::Modern::Vocabulary::Unevaluated::CORE:sort; # opcode