Skip to content

Add scenario benchmarks comparing BVal and Hibernate Validator - #276

Open
jungm wants to merge 1 commit into
masterfrom
perf-0-benchmarks
Open

jungm wants to merge 1 commit into
masterfrom
perf-0-benchmarks

Conversation

@jungm

@jungm jungm commented Oct 5, 2026 •

Copy link
Copy Markdown
Member

Summary

Adds a scenario benchmark that runs the same validations against BVal and Hibernate Validator. The PRs stacked on top of this one quote their numbers against it.

 bval-perf/
 ├── pom.xml                         # + <proc>full</proc>: JDK 23+ no longer runs the JMH processor implicitly
 └── src/test/
     ├── java/org/apache/bval/jsr/
     │   ├── Jsr303Benchmark.java    # + default 2 forks × (3 warmup + 5 measurement) × 1 s
+    │   └── ScenarioBenchmark.java  # 18 scenarios × -p provider=bval|hibernate
+    └── resources/META-INF/services/
+        └── jakarta.el.ExpressionFactory  # Tomcat EL ahead of the bval-jsr test fixture
ScenarioBenchmark
  setUp(provider)        # build factory, generate beans
  check violations once  # a provider cannot look fast by skipping work
  scenarios: mixed valid/invalid beans · explicit group · validateProperty/Value
             method parameters/return value · 1,000-element list · cycles · container elements
             deep graph · 16 built-in constraints (valid/invalid) · composed · class-level · EL message

Evidence

  • Before: no scenario coverage; a plain JMH run uses the defaults (5 forks × 10 × 10 s), over 8 minutes per benchmark.
    After: java -cp <bval-perf test classpath> org.openjdk.jmh.Main ScenarioBenchmark -p provider=bval takes about 5 minutes and gives this baseline:
Baseline (master + this PR)
Benchmark Score B/op
cascadedCycles (ops/ms) 2.29 ± 43% 1,217,820
cascadedList (ops/ms) 0.48 ± 23% 5,862,671
classLevelInvalid (ops/ms) 668 ± 16% 4,264
classLevelValid (ops/ms) 1,004 ± 7% 3,224
composedInvalid (ops/ms) 341 ± 8% 6,092
composedValid (ops/ms) 838 ± 9% 3,240
containerElements (ops/ms) 1.48 ± 15% 1,831,091
deepGraph (ops/ms) 102 ± 8% 31,984
elMessage (ops/ms) 51.6 ± 9% 4,403
executableParameters (ops/ms) 422 ± 5% 6,296
executableReturnValue (ops/ms) 386 ± 9% 6,950
explicitGroup (ops/ms) 472 ± 10% 6,589
mixedDrivers (ops/ms) 487 ± 9% 5,833
validateProperty (ops/ms) 1,361 ± 8% 2,076
validateValue (ops/ms) 2,224 ± 5% 1,352
wideBeanInvalid (ops/ms) 12.4 ± 1% 34,109
wideBeanValid (ops/ms) 146 ± 15% 18,688
Jsr303Benchmark.bvalBootstrapAndValidate (ops/s) 2,845 ± 43% 245,360
Jsr303Benchmark.bvalBuildFactory (ops/s) 11,297 ± 5% 88,057
Jsr303Benchmark.bvalConstraintsFailure (ops/s) 500,080 ± 9% 5,648
Jsr303Benchmark.bvalConstraintsFailureReuseValidator (ops/s) 499,671 ± 11% 5,588
Jsr303Benchmark.bvalConstraintsSuccess (ops/s) 1,213,713 ± 9% 3,224
Jsr303Benchmark.bvalConstraintsSuccessReuseValidator (ops/s) 1,120,020 ± 28% 3,212
Jsr303Benchmark.bvalNoConstraints (ops/s) 100,611,363 ± 21% 0
Jsr303Benchmark.bvalNoConstraintsReuseValidator (ops/s) 119,052,819 ± 24% 0

Merge Danger

Door: two-way

Blast Radius: none

Test-scope only: bval-perf sources and its build; nothing ships.

ScenarioBenchmark runs each scenario against both providers, selected by a
JMH parameter, and checks the expected violation counts once per trial:
mixed valid/invalid beans, explicit groups, validateProperty/Value,
parameter and return value validation, cascading into large collections
and cycles, container element constraints, deep graphs, beans with many
built-in constraints (valid and fully invalid), composed and class-level
constraints, and EL message expressions.

Also run the JMH annotation processor explicitly, as JDK 23+ no longer
does so implicitly, and register Tomcat's ExpressionFactory ahead of the
bval-jsr test fixture that re-resolves its delegate on every call.

Both benchmark classes default to 2 forks of 3 warmup and 5 measurement
iterations of 1 s, so that a plain run takes minutes rather than hours.
@tandraschko

Copy link
Copy Markdown
Member

+1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants