Skip to content

Commit 8344bc0

Browse files
committed
perf: Faster evaluate
Signed-off-by: Dmitry Dygalo <[email protected]>
1 parent 03a6b22 commit 8344bc0

File tree

4 files changed

+11
-3
lines changed

4 files changed

+11
-3
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
### Performance
1010

1111
- `validate` and other APIs returning `Result<_, ValidationError>` are 5–10% faster in some workloads due to the smaller error handle.
12+
- `evaluate`: Eliminated deep clones of unmatched keyword values (e.g., `title`, `description`, `examples`) on every schema node evaluation by using `Arc` internally. Can be multiple times faster for schemas with large annotations.
1213

1314
## [0.36.0] - 2025-11-18
1415

crates/jsonschema-py/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
### Performance
66

77
- `jsonschema_rs.validate()` and `Validator.validate()` run 5–10% faster in some workloads thanks to slimmer `ValidationError` objects.
8+
- `evaluate()`: Avoids copying annotation values on every schema node evaluation. Can be multiple times faster for schemas with large annotations like extensive `title`, `description`, or `examples` fields.
89

910
## [0.36.0] - 2025-11-18
1011

crates/jsonschema/src/evaluation.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,26 @@ use std::{fmt, sync::Arc};
99

1010
/// Annotations associated with an output unit.
1111
#[derive(Debug, Clone, PartialEq)]
12-
pub struct Annotations(serde_json::Value);
12+
pub struct Annotations(Arc<serde_json::Value>);
1313

1414
impl Annotations {
1515
/// Create a new `Annotations` instance.
1616
#[must_use]
1717
pub(crate) fn new(v: serde_json::Value) -> Self {
18+
Annotations(Arc::new(v))
19+
}
20+
21+
/// Create a new `Annotations` instance from an Arc.
22+
#[must_use]
23+
pub(crate) fn from_arc(v: Arc<serde_json::Value>) -> Self {
1824
Annotations(v)
1925
}
2026

2127
/// Returns the inner [`serde_json::Value`] of the annotation.
2228
#[inline]
2329
#[must_use]
2430
pub fn into_inner(self) -> serde_json::Value {
25-
self.0
31+
Arc::try_unwrap(self.0).unwrap_or_else(|arc| (*arc).clone())
2632
}
2733

2834
/// The `serde_json::Value` of the annotation.

crates/jsonschema/src/node.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,7 @@ impl Validate for SchemaNode {
478478
} = *kvals;
479479
let annotations: Option<Annotations> = unmatched_keywords
480480
.as_ref()
481-
.map(|v| Annotations::new((**v).clone()));
481+
.map(|v| Annotations::from_arc(Arc::clone(v)));
482482
Self::evaluate_subschemas(
483483
instance,
484484
location,

0 commit comments

Comments
 (0)