@@ -10,6 +10,7 @@ use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criteri
1010
1111use a2ml:: parser:: parse;
1212use a2ml:: renderer:: render;
13+ use a2ml:: types:: TrustLevel ;
1314
1415// ---------------------------------------------------------------------------
1516// Document fixtures
@@ -202,6 +203,116 @@ fn bench_roundtrip_large(c: &mut Criterion) {
202203 } ) ;
203204}
204205
206+ // ---------------------------------------------------------------------------
207+ // Attestation-heavy document benchmarks
208+ //
209+ // Attestation blocks (`!attest`) are parsed separately from the main document
210+ // tree. These benchmarks measure the cost of parsing documents that contain
211+ // many attestation records — the typical pattern in multi-reviewer workflows.
212+ // ---------------------------------------------------------------------------
213+
214+ /// A document containing 20 attestation records.
215+ fn attestation_heavy_document ( ) -> String {
216+ let mut doc = String :: with_capacity ( 4_096 ) ;
217+ doc. push_str ( "# Attested Document\n \n @version 1.0\n \n " ) ;
218+ doc. push_str ( "This document has been reviewed by many parties.\n \n " ) ;
219+
220+ let roles = [ "author" , "reviewer" , "auditor" , "approver" , "witness" ] ;
221+ let trusts = [ "reviewed" , "verified" , "automated" , "manual" , "attested" ] ;
222+ for i in 0 ..20 {
223+ doc. push_str ( & format ! (
224+ "!attest identity=Agent{} role={} trust={} ts=2026-01-{:02}\n " ,
225+ i,
226+ roles[ i % roles. len( ) ] ,
227+ trusts[ i % trusts. len( ) ] ,
228+ ( i % 28 ) + 1 ,
229+ ) ) ;
230+ }
231+ doc
232+ }
233+
234+ /// A document containing 30 directives (`@`-prefixed metadata lines).
235+ fn directive_heavy_document ( ) -> String {
236+ let mut doc = String :: with_capacity ( 4_096 ) ;
237+ doc. push_str ( "# Directive Document\n \n " ) ;
238+
239+ let keys = [
240+ "version" ,
241+ "require" ,
242+ "schema" ,
243+ "lang" ,
244+ "encoding" ,
245+ "created" ,
246+ "modified" ,
247+ "author" ,
248+ "project" ,
249+ "stability" ,
250+ ] ;
251+ for i in 0 ..30 {
252+ doc. push_str ( & format ! (
253+ "@{} value-{}\n " ,
254+ keys[ i % keys. len( ) ] ,
255+ i
256+ ) ) ;
257+ }
258+ doc. push_str ( "\n Body paragraph after directives.\n " ) ;
259+ doc
260+ }
261+
262+ /// Benchmark parsing a document with many attestation records.
263+ fn bench_parse_attestation_heavy ( c : & mut Criterion ) {
264+ let input = attestation_heavy_document ( ) ;
265+ c. bench_function ( "parse/attestation_heavy_20" , |b| {
266+ b. iter ( || {
267+ let doc = parse ( black_box ( & input) ) . expect ( "attestation document must parse" ) ;
268+ black_box ( doc) ;
269+ } ) ;
270+ } ) ;
271+ }
272+
273+ /// Benchmark parsing a document with many directives.
274+ fn bench_parse_directive_heavy ( c : & mut Criterion ) {
275+ let input = directive_heavy_document ( ) ;
276+ c. bench_function ( "parse/directive_heavy_30" , |b| {
277+ b. iter ( || {
278+ let doc = parse ( black_box ( & input) ) . expect ( "directive document must parse" ) ;
279+ black_box ( doc) ;
280+ } ) ;
281+ } ) ;
282+ }
283+
284+ /// Benchmark extracting attestation records from a parsed document.
285+ ///
286+ /// Isolates the attestation-access pattern used when verifying provenance
287+ /// chains — separate from the overall parse cost.
288+ fn bench_attestation_access ( c : & mut Criterion ) {
289+ let input = attestation_heavy_document ( ) ;
290+ let doc = parse ( & input) . expect ( "parse attestation document" ) ;
291+
292+ c. bench_function ( "attestation/access_20_records" , |b| {
293+ b. iter ( || {
294+ // Simulate a verifier walking the full attestation chain.
295+ let count = black_box ( & doc)
296+ . attestations
297+ . iter ( )
298+ . filter ( |a| a. trust_level == TrustLevel :: Verified )
299+ . count ( ) ;
300+ black_box ( count) ;
301+ } ) ;
302+ } ) ;
303+ }
304+
305+ /// Benchmark render of an attestation-heavy document (provenance serialisation).
306+ fn bench_render_attestation_heavy ( c : & mut Criterion ) {
307+ let doc = parse ( & attestation_heavy_document ( ) ) . expect ( "parse" ) ;
308+ c. bench_function ( "render/attestation_heavy_20" , |b| {
309+ b. iter ( || {
310+ let output = render ( black_box ( & doc) ) . expect ( "render must succeed" ) ;
311+ black_box ( output) ;
312+ } ) ;
313+ } ) ;
314+ }
315+
205316// ---------------------------------------------------------------------------
206317// Criterion registration
207318// ---------------------------------------------------------------------------
@@ -227,4 +338,12 @@ criterion_group!(
227338 bench_roundtrip_large
228339) ;
229340
230- criterion_main ! ( parse_benches, render_benches, roundtrip_benches) ;
341+ criterion_group ! (
342+ attestation_benches,
343+ bench_parse_attestation_heavy,
344+ bench_parse_directive_heavy,
345+ bench_attestation_access,
346+ bench_render_attestation_heavy,
347+ ) ;
348+
349+ criterion_main ! ( parse_benches, render_benches, roundtrip_benches, attestation_benches) ;
0 commit comments