Skip to content

Commit

Permalink
Don't uselessly recombine registries each time we recurse into subsch…
Browse files Browse the repository at this point in the history
…emas.

Also add a benchmark via @robherring to ensure we compare these timings
(validating with or without a registry which isn't really being used).

Fixes a ~4-5x slowdown. These are now on par with each other.

Closes: #1088
  • Loading branch information
Julian committed Jun 5, 2023
1 parent b62bcfb commit 1240e68
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 9 deletions.
35 changes: 35 additions & 0 deletions jsonschema/benchmarks/unused_registry.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
"""
An unused schema registry should not cause slower validation.
"Unused" here means one where no reference resolution is occurring anyhow.
See https://github.com/python-jsonschema/jsonschema/issues/1088.
"""
from pyperf import Runner
from referencing import Registry
from referencing.jsonschema import DRAFT201909

from jsonschema import Draft201909Validator

registry = Registry().with_resource(
"urn:example:foo",
DRAFT201909.create_resource({})
)

schema = {"$ref": "https://json-schema.org/draft/2019-09/schema"}
instance = {"maxLength": 4}

no_registry = Draft201909Validator(schema)
with_useless_registry = Draft201909Validator(schema, registry=registry)

if __name__ == "__main__":
runner = Runner()

runner.bench_func(
"no registry",
lambda: no_registry.is_valid(instance),
)
runner.bench_func(
"useless registry",
lambda: with_useless_registry.is_valid(instance),
)
13 changes: 4 additions & 9 deletions jsonschema/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,12 +224,7 @@ class Validator:
format_checker: _format.FormatChecker | None = field(default=None)
# TODO: include new meta-schemas added at runtime
_registry: referencing.jsonschema.SchemaRegistry = field(
default=_DEFAULT_REGISTRY,
converter=lambda value: (
_DEFAULT_REGISTRY
if value is _DEFAULT_REGISTRY
else SPECIFICATIONS.combine(value)
),
default=referencing.Registry(),
kw_only=True,
repr=False,
)
Expand Down Expand Up @@ -274,9 +269,9 @@ def evolve(self, **changes):

def __attrs_post_init__(self):
if self._resolver is None:
self._resolver = self._registry.resolver_with_root(
resource=specification.create_resource(self.schema),
)
registry = _DEFAULT_REGISTRY.combine(self._registry)
resource = specification.create_resource(self.schema)
self._resolver = registry.resolver_with_root(resource)

@classmethod
def check_schema(cls, schema, format_checker=_UNSET):
Expand Down

0 comments on commit 1240e68

Please sign in to comment.