Skip to content

Commit

Permalink
build: Add boon to benchmarks
Browse files Browse the repository at this point in the history
Signed-off-by: Dmitry Dygalo <[email protected]>
  • Loading branch information
Stranger6667 committed May 15, 2024
1 parent dbe6c90 commit d509b4b
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 1 deletion.
8 changes: 7 additions & 1 deletion jsonschema/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,12 @@ getrandom = { version = "0.2", features = ["js"] }

[dev-dependencies]
bench_helpers = { path = "../bench_helpers" }
boon = "0.5"
codspeed-criterion-compat = "2.6.0"
criterion = { version = "0.5.1", features = [], default-features = false }
json_schema_test_suite = { version = "0.3.0", path = "../jsonschema-test-suite" }
jsonschema-valid = "0.5"
lazy_static = "1.4" # Needed for json schema test suite
lazy_static = "1.4" # Needed for json schema test suite
mockito = "0.31"
paste = "1.0"
test-case = "3"
Expand All @@ -93,6 +94,11 @@ name = "valico"
harness = false
name = "jsonschema_valid"

# Benchmarks for `boon`
[[bench]]
harness = false
name = "boon"

[profile.release]
codegen-units = 1
lto = "fat"
128 changes: 128 additions & 0 deletions jsonschema/benches/boon.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
use bench_helpers::{
bench_citm, bench_fast, bench_geojson, bench_keywords, bench_openapi, bench_swagger,
};
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
use jsonschema::JSONSchema;
use serde_json::Value;

macro_rules! boon_bench {
($c:tt, $name:expr, $schema:ident, $instance:ident) => {{
let mut schemas = boon::Schemas::new();
let mut compiler = boon::Compiler::new();
compiler.add_resource("schema.json", $schema).unwrap();
let id = compiler.compile("schema.json", &mut schemas).unwrap();
assert!(schemas.validate(&$instance, id).is_ok(), "Invalid instance");
$c.bench_function(&format!("{} boon/validate", $name), |b| {
b.iter(|| {
let _ = schemas.validate(&$instance, id).is_ok();
});
});
}};
}

fn large_schemas(c: &mut Criterion) {
// Open API JSON Schema
// Only `jsonschema` works correctly - other libraries do not recognize `zuora` as valid
bench_openapi(&mut |name, schema, instance| boon_bench!(c, name, schema, instance));
// Swagger JSON Schema
bench_swagger(&mut |name, schema, instance| boon_bench!(c, name, schema, instance));
// Canada borders in GeoJSON
bench_geojson(&mut |name, schema, instance| boon_bench!(c, name, schema, instance));
// CITM catalog
bench_citm(&mut |name, schema, instance| boon_bench!(c, name, schema, instance));
}

fn fast_schema(c: &mut Criterion) {
bench_fast(&mut |name, schema, valid, invalid| {
let mut schemas = boon::Schemas::new();
let mut compiler = boon::Compiler::new();
compiler.add_resource("schema.json", schema).unwrap();
let id = compiler.compile("schema.json", &mut schemas).unwrap();
assert!(schemas.validate(&valid, id).is_ok(), "Invalid instance");
assert!(schemas.validate(&invalid, id).is_err(), "Invalid instance");
c.bench_function(&format!("{} boon/is_valid/valid", name), |b| {
b.iter(|| {
let _ = schemas.validate(&valid, id).is_ok();
});
});
c.bench_function(&format!("{} boon/is_valid/invalid", name), |b| {
b.iter(|| {
let _ = schemas.validate(&invalid, id).is_ok();
});
});
});
}

fn keywords(c: &mut Criterion) {
bench_keywords(
c,
&|_: &str| false,
&|schema: &Value, instance: &Value| {
let compiled = JSONSchema::compile(schema).expect("Valid schema");
compiled.is_valid(instance)
},
&mut |c: &mut Criterion, name: &str, schema: &Value| {
c.bench_with_input(
BenchmarkId::new(name, "jsonschema_rs/compile"),
schema,
|b, schema| {
b.iter(|| {
JSONSchema::compile(schema).expect("Valid schema");
})
},
);
},
validate_valid,
validate_invalid,
)
}

fn validate_valid(c: &mut Criterion, name: &str, schema: &Value, instance: &Value) {
let compiled = JSONSchema::compile(schema).expect("Valid schema");
c.bench_with_input(
BenchmarkId::new(name, "jsonschema_rs/is_valid/valid"),
instance,
|b, instance| {
b.iter(|| {
let _ = compiled.is_valid(instance);
})
},
);
c.bench_with_input(
BenchmarkId::new(name, "jsonschema_rs/validate/valid"),
instance,
|b, instance| {
b.iter(|| {
compiled.validate(instance).ok();
})
},
);
}

fn validate_invalid(c: &mut Criterion, name: &str, schema: &Value, instance: &Value) {
let compiled = JSONSchema::compile(schema).expect("Valid schema");
c.bench_with_input(
BenchmarkId::new(name, "jsonschema_rs/is_valid/invalid"),
instance,
|b, instance| {
b.iter(|| {
let _ = compiled.is_valid(instance);
})
},
);
c.bench_with_input(
BenchmarkId::new(name, "jsonschema_rs/validate/invalid"),
instance,
|b, instance| {
b.iter(|| {
let _: Vec<_> = compiled
.validate(instance)
.expect_err("There should be errors")
.collect();
})
},
);
}

criterion_group!(arbitrary, large_schemas, fast_schema);
criterion_main!(arbitrary);

0 comments on commit d509b4b

Please sign in to comment.