← Index
NYTProf Performance Profile   « line view »
For ../prof.pl
  Run on Thu Dec 15 15:23:56 2022
Reported on Thu Dec 15 15:27:04 2022

Filename/Users/ether/git/JSON-Schema-Modern/lib/JSON/Schema/Modern/Vocabulary/Unevaluated.pm
StatementsExecuted 129100 statements in 146ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
374211103ms353msJSON::Schema::Modern::Vocabulary::Unevaluated::::_eval_keyword_unevaluatedPropertiesJSON::Schema::Modern::Vocabulary::Unevaluated::_eval_keyword_unevaluatedProperties
3742112.54ms2.54msJSON::Schema::Modern::Vocabulary::Unevaluated::::CORE:sortJSON::Schema::Modern::Vocabulary::Unevaluated::CORE:sort (opcode)
15411978µs5.36msJSON::Schema::Modern::Vocabulary::Unevaluated::::_traverse_keyword_unevaluatedPropertiesJSON::Schema::Modern::Vocabulary::Unevaluated::_traverse_keyword_unevaluatedProperties
11130µs33µsJSON::Schema::Modern::Vocabulary::Applicator::::BEGIN@1.309 JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@1.309
11119µs19µsJSON::Schema::Modern::Vocabulary::Unevaluated::::BEGIN@9JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@9
11118µs63µsJSON::Schema::Modern::Vocabulary::Unevaluated::::BEGIN@17JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@17
11116µs43µsJSON::Schema::Modern::Vocabulary::Unevaluated::::BEGIN@16JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@16
11112µs662µsJSON::Schema::Modern::Vocabulary::Unevaluated::::BEGIN@11JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@11
11112µs37µsJSON::Schema::Modern::Vocabulary::Unevaluated::::BEGIN@13JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@13
22111µs15µsJSON::Schema::Modern::Vocabulary::Unevaluated::::keywordsJSON::Schema::Modern::Vocabulary::Unevaluated::keywords
11110µs24µsJSON::Schema::Modern::Vocabulary::Unevaluated::::BEGIN@14JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@14
11110µs25µsJSON::Schema::Modern::Vocabulary::Unevaluated::::BEGIN@15JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@15
1119µs344µsJSON::Schema::Modern::Vocabulary::Unevaluated::::BEGIN@10JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@10
1117µs40µsJSON::Schema::Modern::Vocabulary::Applicator::::BEGIN@2.310 JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@2.310
1117µs103µsJSON::Schema::Modern::Vocabulary::Unevaluated::::BEGIN@12JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@12
1116µs32µsJSON::Schema::Modern::Vocabulary::Unevaluated::::BEGIN@18JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@18
1116µs196µsJSON::Schema::Modern::Vocabulary::Unevaluated::::BEGIN@19JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@19
2114µs4µ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__[:118]JSON::Schema::Modern::Vocabulary::Unevaluated::__ANON__[:118]
0000s0sJSON::Schema::Modern::Vocabulary::Unevaluated::::__ANON__[:56]JSON::Schema::Modern::Vocabulary::Unevaluated::__ANON__[:56]
0000s0sJSON::Schema::Modern::Vocabulary::Unevaluated::::__ANON__[:72]JSON::Schema::Modern::Vocabulary::Unevaluated::__ANON__[:72]
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
1233µs236µs
# spent 33µs (30+3) within JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@1.309 which was called: # once (30µs+3µs) by JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@21 at line 1
use strict;
# spent 33µs making 1 call to JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@1.309 # spent 3µs making 1 call to strict::import
22339µs273µs
# spent 40µs (7+33) within JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@2.310 which was called: # once (7µs+33µs) by JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@21 at line 2
use warnings;
# spent 40µs making 1 call to JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@2.310 # spent 33µ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.559';
8
9262µs119µs
# spent 19µs within JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@9 which was called: # once (19µs+0s) by JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@21 at line 9
use 5.020;
10235µs2679µs
# spent 344µs (9+335) within JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@10 which was called: # once (9µs+335µs) by JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@21 at line 10
use Moo;
# spent 344µs making 1 call to JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@10 # spent 335µs making 1 call to Moo::import
11340µs31.31ms
# spent 662µs (12+650) within JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@11 which was called: # once (12µs+650µs) by JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@21 at line 11
use strictures 2;
# spent 662µs making 1 call to JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@11 # spent 630µs making 1 call to strictures::import # spent 19µs making 1 call to strictures::VERSION
12238µs2199µs
# spent 103µs (7+96) within JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@12 which was called: # once (7µs+96µs) by JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@21 at line 12
use experimental qw(signatures postderef);
# spent 103µs making 1 call to JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@12 # spent 96µs making 1 call to experimental::import
13224µs240µs
# spent 37µs (12+25) within JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@13 which was called: # once (12µs+25µs) by JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@21 at line 13
use if "$]" >= 5.022, experimental => 're_strict';
# spent 37µs making 1 call to JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@13 # spent 3µs making 1 call to if::import
14219µ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
15252µs225µs
# spent 25µs (10+15) within JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@15 which was called: # once (10µs+15µs) by JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@21 at line 15
no if "$]" >= 5.033001, feature => 'multidimensional';
# spent 25µs making 1 call to JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@15 # spent 0s making 1 call to if::unimport
16226µs246µs
# spent 43µs (16+27) within JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@16 which was called: # once (16µs+27µs) by JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@21 at line 16
no if "$]" >= 5.033006, feature => 'bareword_filehandles';
# spent 43µs making 1 call to JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@16 # spent 3µs making 1 call to if::unimport
17339µs381µs
# spent 63µs (18+45) within JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@17 which was called: # once (18µs+45µs) by JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@21 at line 17
use List::Util 1.45 qw(any max);
# spent 63µs making 1 call to JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@17 # spent 10µs making 1 call to List::Util::import # spent 8µs making 1 call to UNIVERSAL::VERSION
18213µs258µs
# spent 32µs (6+26) within JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@18 which was called: # once (6µs+26µ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 26µs making 1 call to Exporter::import
192710µs2386µs
# spent 196µs (6+190) within JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@19 which was called: # once (6µs+190µs) by JSON::Schema::Modern::Vocabulary::Applicator::BEGIN@21 at line 19
use namespace::clean;
# spent 196µs making 1 call to JSON::Schema::Modern::Vocabulary::Unevaluated::BEGIN@19 # spent 190µs making 1 call to namespace::clean::import
20
2113µs1350µswith 'JSON::Schema::Modern::Vocabulary';
# spent 350µ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/git/JSON-Schema-Modern/lib/JSON/Schema/Modern.pm:709] at line 705 of /Users/ether/git/JSON-Schema-Modern/lib/JSON/Schema/Modern.pm
sub vocabulary {
2412µ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 337 of /Users/ether/git/JSON-Schema-Modern/lib/JSON/Schema/Modern/Vocabulary/Core.pm, avg 500ns/call
sub evaluation_order { 7 }
28
29# This vocabulary should be evaluated after the Applicator vocabulary.
3062µs
# spent 15µs (11+4) within JSON::Schema::Modern::Vocabulary::Unevaluated::keywords which was called 2 times, avg 7µs/call: # once (7µs+1000ns) by JSON::Schema::Modern::_traverse_subschema at line 480 of /Users/ether/git/JSON-Schema-Modern/lib/JSON/Schema/Modern.pm # once (4µs+3µs) by JSON::Schema::Modern::_eval_subschema at line 572 of /Users/ether/git/JSON-Schema-Modern/lib/JSON/Schema/Modern.pm
sub keywords ($self, $spec_version) {
3129µs24µs die 'Unevaluated not implemented in '.$spec_version if $spec_version =~ /^draft[467]$/;
# spent 4µs making 2 calls to JSON::Schema::Modern::Vocabulary::Unevaluated::CORE:match, avg 2µs/call
3224µs qw(unevaluatedItems unevaluatedProperties);
33}
34
35sub _traverse_keyword_unevaluatedItems ($self, $schema, $state) {
36 $self->traverse_subschema($schema, $state);
37}
38
39sub _eval_keyword_unevaluatedItems ($self, $data, $schema, $state) {
40 abort($state, 'EXCEPTION: "unevaluatedItems" keyword present, but annotation collection is disabled')
41 if not $state->{collect_annotations};
42
43 abort($state, 'EXCEPTION: "unevaluatedItems" keyword present, but short_circuit is enabled: results unreliable')
44 if $state->{short_circuit};
45
46 return 1 if not is_type('array', $data);
47
48 my @annotations = local_annotations($state);
49
50 # a relevant keyword already produced a 'true' annotation at this location
51 my @boolean_annotation_keywords =
52 $state->{spec_version} eq 'draft2019-09' ? qw(items additionalItems unevaluatedItems)
53 : qw(prefixItems items contains unevaluatedItems);
54 my %bools; @bools{@boolean_annotation_keywords} = (1)x@boolean_annotation_keywords;
55 return 1
56 if any { $bools{$_->{keyword}} && is_type('boolean', $_->{annotation}) && $_->{annotation} }
57 @annotations;
58
59 # otherwise, evaluate at every instance item greater than the max of all 'prefixItems'/numeric
60 # 'items' annotations that isn't in a 'contains' annotation
61 my $max_index_annotation_keyword = $state->{spec_version} eq 'draft2019-09' ? 'items' : 'prefixItems';
62 my $last_index = max(-1, grep is_type('integer', $_),
63 map +($_->{keyword} eq $max_index_annotation_keyword ? $_->{annotation} : ()), @annotations);
64
65 return 1 if $last_index == $data->$#*;
66
67 my @contains_annotation_indexes = $state->{spec_version} eq 'draft2019-09' ? ()
68 : map +($_->{keyword} eq 'contains' ? $_->{annotation}->@* : ()), @annotations;
69
70 my $valid = 1;
71 foreach my $idx ($last_index+1 .. $data->$#*) {
72 next if any { $idx == $_ } @contains_annotation_indexes;
73 if (is_type('boolean', $schema->{unevaluatedItems})) {
74 next if $schema->{unevaluatedItems};
75 $valid = E({ %$state, data_path => $state->{data_path}.'/'.$idx },
76 'additional item not permitted')
77 }
78 else {
79 if ($self->eval($data->[$idx], $schema->{unevaluatedItems},
80 +{ %$state, data_path => $state->{data_path}.'/'.$idx,
81 schema_path => $state->{schema_path}.'/unevaluatedItems',
82 collect_annotations => $state->{collect_annotations} & ~1 })) {
83 next;
84 }
85
86 $valid = 0;
87 }
88 last if $state->{short_circuit};
89 }
90
91 A($state, true);
92 return E($state, 'subschema is not valid against all additional items') if not $valid;
93 return 1;
94}
95
96616105µs
# spent 5.36ms (978µs+4.38) within JSON::Schema::Modern::Vocabulary::Unevaluated::_traverse_keyword_unevaluatedProperties which was called 154 times, avg 35µs/call: # 154 times (978µs+4.38ms) by JSON::Schema::Modern::_traverse_subschema at line 492 of /Users/ether/git/JSON-Schema-Modern/lib/JSON/Schema/Modern.pm, avg 35µs/call
sub _traverse_keyword_unevaluatedProperties ($self, $schema, $state) {
97154743µs1543.15ms $self->traverse_subschema($schema, $state);
# spent 4.38ms making 154 calls to JSON::Schema::Modern::Vocabulary::traverse_subschema, avg 28µs/call, recursion: max depth 2, sum of overlapping time 1.23ms
98}
99
100187103.37ms
# spent 353ms (103+250) within JSON::Schema::Modern::Vocabulary::Unevaluated::_eval_keyword_unevaluatedProperties which was called 3742 times, avg 94µs/call: # 3742 times (103ms+250ms) by JSON::Schema::Modern::_eval_subschema at line 587 of /Users/ether/git/JSON-Schema-Modern/lib/JSON/Schema/Modern.pm, avg 94µs/call
sub _eval_keyword_unevaluatedProperties ($self, $data, $schema, $state) {
101 abort($state, 'EXCEPTION: "unevaluatedProperties" keyword present, but annotation collection is disabled')
10237421.69ms if not $state->{collect_annotations};
103
104 abort($state, 'EXCEPTION: "unevaluatedProperties" keyword present, but short_circuit is enabled: results unreliable')
10537421.46ms if $state->{short_circuit};
106
10737424.19ms37426.18ms return 1 if not is_type('object', $data);
# spent 6.18ms making 3742 calls to JSON::Schema::Modern::Utilities::is_type, avg 2µs/call
108
109 my @evaluated_properties = map {
1101272910.8ms374228.2ms my $keyword = $_->{keyword};
# spent 28.2ms making 3742 calls to JSON::Schema::Modern::Utilities::local_annotations, avg 8µs/call
111 (grep $keyword eq $_, qw(properties additionalProperties patternProperties unevaluatedProperties))
11289879.07ms ? $_->{annotation}->@* : ();
113 } local_annotations($state);
114
1153742691µs my $valid = 1;
1163742671µs my @properties;
117374226.8ms37422.54ms foreach my $property (sort keys %$data) {
# spent 2.54ms making 3742 calls to JSON::Schema::Modern::Vocabulary::Unevaluated::CORE:sort, avg 680ns/call
1185418237.5ms797815.2ms next if any { $_ eq $property } @evaluated_properties;
# spent 15.2ms making 7978 calls to List::Util::any, avg 2µs/call
119 push @properties, $property;
120
121 if (is_type('boolean', $schema->{unevaluatedProperties})) {
122 next if $schema->{unevaluatedProperties};
123 $valid = E({ %$state, data_path => jsonp($state->{data_path}, $property) },
124 'additional property not permitted');
125 }
126 else {
127 if ($self->eval($data->{$property}, $schema->{unevaluatedProperties},
128 +{ %$state, data_path => jsonp($state->{data_path}, $property),
129 schema_path => $state->{schema_path}.'/unevaluatedProperties',
130 collect_annotations => $state->{collect_annotations} & ~1 })) {
131 next;
132 }
133
134 $valid = 0;
135 }
136 last if $state->{short_circuit};
137 }
138
13937423.38ms3742198ms A($state, \@properties);
# spent 198ms making 3742 calls to JSON::Schema::Modern::Utilities::A, avg 53µs/call
1403742834µs return E($state, 'not all additional properties are valid') if not $valid;
141374243.5ms return 1;
142}
143
144110µs1;
145130µs1455µs__END__
 
# spent 4µs within JSON::Schema::Modern::Vocabulary::Unevaluated::CORE:match which was called 2 times, avg 2µs/call: # 2 times (4µ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 2.54ms within JSON::Schema::Modern::Vocabulary::Unevaluated::CORE:sort which was called 3742 times, avg 680ns/call: # 3742 times (2.54ms+0s) by JSON::Schema::Modern::Vocabulary::Unevaluated::_eval_keyword_unevaluatedProperties at line 117, avg 680ns/call
sub JSON::Schema::Modern::Vocabulary::Unevaluated::CORE:sort; # opcode