Skip to content

Commit 52b939e

Browse files
committed
perf: Add unevaluated items benches
Signed-off-by: Dmitry Dygalo <[email protected]>
1 parent fc99a21 commit 52b939e

File tree

2 files changed

+182
-0
lines changed

2 files changed

+182
-0
lines changed

crates/jsonschema/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,3 +96,7 @@ name = "location"
9696
[[bench]]
9797
harness = false
9898
name = "unevaluated_properties"
99+
100+
[[bench]]
101+
harness = false
102+
name = "unevaluated_items"
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
#[cfg(not(target_arch = "wasm32"))]
2+
mod bench {
3+
use codspeed_criterion_compat::{criterion_group, BenchmarkId, Criterion};
4+
use serde_json::{json, Value};
5+
use std::hint::black_box;
6+
7+
fn large_schema() -> Value {
8+
json!({
9+
"$schema": "https://json-schema.org/draft/2020-12/schema",
10+
"type": "array",
11+
"prefixItems": [
12+
{"type": "string"},
13+
{"type": "number"},
14+
{"type": "boolean"}
15+
],
16+
"contains": {
17+
"type": "object",
18+
"properties": {
19+
"special": {"type": "boolean"}
20+
}
21+
},
22+
"allOf": [
23+
{
24+
"if": {
25+
"contains": {"const": "trigger"}
26+
},
27+
"then": {
28+
"prefixItems": [
29+
{"type": "string"},
30+
{"type": "number"},
31+
{"type": "boolean"},
32+
{"type": "string"}
33+
]
34+
},
35+
"else": {
36+
"prefixItems": [
37+
{"type": "string"},
38+
{"type": "number"},
39+
{"type": "boolean"},
40+
{"type": "number"}
41+
]
42+
}
43+
}
44+
],
45+
"anyOf": [
46+
{
47+
"contains": {"type": "string"}
48+
},
49+
{
50+
"contains": {"type": "number"}
51+
}
52+
],
53+
"oneOf": [
54+
{
55+
"prefixItems": [
56+
{"type": "string"},
57+
{"type": "number"},
58+
{"type": "boolean"},
59+
{"type": "string"},
60+
{"type": "array"}
61+
]
62+
},
63+
{
64+
"prefixItems": [
65+
{"type": "string"},
66+
{"type": "number"},
67+
{"type": "boolean"},
68+
{"type": "number"},
69+
{"type": "object"}
70+
]
71+
}
72+
],
73+
"unevaluatedItems": false
74+
})
75+
}
76+
77+
fn large_invalid_instance() -> Value {
78+
json!([
79+
"string",
80+
42,
81+
true,
82+
123,
83+
{"special": true},
84+
"unexpected" // This should trigger unevaluatedItems: false
85+
])
86+
}
87+
88+
fn bench_build(c: &mut Criterion, name: &str, schema: &Value) {
89+
c.bench_with_input(BenchmarkId::new("build", name), schema, |b, schema| {
90+
b.iter_with_large_drop(|| jsonschema::draft202012::new(schema).unwrap());
91+
});
92+
}
93+
94+
fn bench_is_valid(
95+
c: &mut Criterion,
96+
name: &str,
97+
validator: &jsonschema::Validator,
98+
instance: &Value,
99+
) {
100+
c.bench_with_input(
101+
BenchmarkId::new("is_valid", name),
102+
instance,
103+
|b, instance| {
104+
b.iter(|| {
105+
black_box(validator.is_valid(instance));
106+
});
107+
},
108+
);
109+
}
110+
111+
fn bench_validate(
112+
c: &mut Criterion,
113+
name: &str,
114+
validator: &jsonschema::Validator,
115+
instance: &Value,
116+
) {
117+
c.bench_with_input(
118+
BenchmarkId::new("validate", name),
119+
instance,
120+
|b, instance| {
121+
b.iter(|| {
122+
let _ = black_box(validator.validate(instance));
123+
});
124+
},
125+
);
126+
}
127+
128+
fn bench_apply(
129+
c: &mut Criterion,
130+
name: &str,
131+
validator: &jsonschema::Validator,
132+
instance: &Value,
133+
) {
134+
c.bench_with_input(BenchmarkId::new("apply", name), instance, |b, instance| {
135+
b.iter_with_large_drop(|| validator.apply(instance).basic());
136+
});
137+
}
138+
139+
fn bench_iter_errors(
140+
c: &mut Criterion,
141+
name: &str,
142+
validator: &jsonschema::Validator,
143+
instance: &Value,
144+
) {
145+
c.bench_with_input(
146+
BenchmarkId::new("iter_errors", name),
147+
instance,
148+
|b, instance| {
149+
b.iter(|| {
150+
for error in validator.iter_errors(instance) {
151+
black_box(error);
152+
}
153+
});
154+
},
155+
);
156+
}
157+
158+
fn run_benchmarks(c: &mut Criterion) {
159+
let large = large_schema();
160+
bench_build(c, "unevaluated_items", &large);
161+
162+
let validator = jsonschema::draft202012::new(&large).unwrap();
163+
let invalid = large_invalid_instance();
164+
165+
bench_is_valid(c, "unevaluated_items", &validator, &invalid);
166+
bench_validate(c, "unevaluated_items", &validator, &invalid);
167+
bench_apply(c, "unevaluated_items", &validator, &invalid);
168+
bench_iter_errors(c, "unevaluated_items", &validator, &invalid);
169+
}
170+
171+
criterion_group!(benches, run_benchmarks);
172+
}
173+
174+
#[cfg(not(target_arch = "wasm32"))]
175+
codspeed_criterion_compat::criterion_main!(bench::benches);
176+
177+
#[cfg(target_arch = "wasm32")]
178+
fn main() {}

0 commit comments

Comments
 (0)