corpus: 67 unique PDFs from icdar2013-competition-dataset-with-gt, 2 iters per tool
[  1/67] eu-001.pdf: spectre[strict=Y=   5.0ms,len=   5.0ms,ch=   4809]  pymupdf=   5.8ms(   4849)  pdfminer.six= 119.5ms(   4942)  pdfplumber= 180.0ms(   4318)  
[  2/67] eu-002.pdf: spectre[strict=Y=   2.5ms,len=   2.5ms,ch=   1884]  pymupdf=   3.1ms(   1600)  pdfminer.six=  38.9ms(   1735)  pdfplumber=  51.8ms(   1474)  
[  3/67] eu-003.pdf: spectre[strict=Y=   1.6ms,len=   1.5ms,ch=   1529]  pymupdf=   1.7ms(   1585)  pdfminer.six=  24.5ms(   1655)  pdfplumber=  45.4ms(   1386)  
[  4/67] eu-004.pdf: spectre[strict=Y=  11.8ms,len=  11.8ms,ch=  31941]  pymupdf=  13.9ms(  31882)  pdfminer.six= 381.2ms(  32655)  pdfplumber= 778.8ms(  31333)  
[  5/67] eu-005.pdf: spectre[strict=Y=   2.0ms,len=   2.0ms,ch=   3507]  pymupdf=   3.1ms(   3493)  pdfminer.six=  81.0ms(   3657)  pdfplumber= 100.5ms(   3477)  
[  6/67] eu-006.pdf: spectre[strict=Y=   2.3ms,len=   2.3ms,ch=   5601]  pymupdf=   3.9ms(   5589)  pdfminer.six=  56.5ms(   5710)  pdfplumber= 110.5ms(   5555)  
[  7/67] eu-007.pdf: spectre[strict=Y=   4.7ms,len=   4.8ms,ch=  12991]  pymupdf=   6.5ms(  12890)  pdfminer.six= 123.9ms(  13189)  pdfplumber= 242.6ms(  12624)  
[  8/67] eu-008.pdf: spectre[strict=Y=   2.0ms,len=   2.0ms,ch=   3640]  pymupdf=   3.2ms(   3649)  pdfminer.six=  38.2ms(   3942)  pdfplumber=  75.0ms(   3482)  
[  9/67] eu-009a.pdf: spectre[strict=Y=   1.8ms,len=   1.6ms,ch=   1713]  pymupdf=   1.9ms(   1702)  pdfminer.six=  20.1ms(   1832)  pdfplumber=  34.7ms(   1627)  
[ 10/67] eu-010.pdf: spectre[strict=Y=   1.8ms,len=   1.7ms,ch=   1080]  pymupdf=   2.3ms(   1108)  pdfminer.six=  15.0ms(   1156)  pdfplumber=  24.8ms(    986)  
[ 11/67] eu-011.pdf: spectre[strict=Y=  20.6ms,len=  21.0ms,ch=  11906]  pymupdf=  13.9ms(  11751)  pdfminer.six= 652.5ms(  12546)  pdfplumber= 863.8ms(  11446)  
[ 12/67] eu-012.pdf: spectre[strict=Y=   4.4ms,len=   4.3ms,ch=  11733]  pymupdf=   5.9ms(  11729)  pdfminer.six= 132.0ms(  12491)  pdfplumber= 207.7ms(  11292)  
[ 13/67] eu-013.pdf: spectre[strict=Y=   6.8ms,len=   7.1ms,ch=  30570]  pymupdf=  10.3ms(  30220)  pdfminer.six= 233.5ms(  31895)  pdfplumber= 491.1ms(  29590)  
[ 14/67] eu-014.pdf: spectre[strict=Y=   4.3ms,len=   4.0ms,ch=  12614]  pymupdf=   5.8ms(  12516)  pdfminer.six=  88.9ms(  13261)  pdfplumber= 213.5ms(  12102)  
[ 15/67] eu-015.pdf: spectre[strict=Y=   2.4ms,len=   2.6ms,ch=   2732]  pymupdf=   2.6ms(   2925)  pdfminer.six=  63.8ms(   3038)  pdfplumber=  96.7ms(   2901)  
[ 16/67] eu-016.pdf: spectre[strict=Y=   5.5ms,len=   5.8ms,ch=   4235]  pymupdf=  13.8ms(   4229)  pdfminer.six= 140.2ms(   4585)  pdfplumber= 155.4ms(   4160)  
[ 17/67] eu-017.pdf: spectre[strict=Y=   5.8ms,len=   5.9ms,ch=   4184]  pymupdf=   6.2ms(   4175)  pdfminer.six= 150.5ms(   4638)  pdfplumber= 169.6ms(   4120)  
[ 18/67] eu-018.pdf: spectre[strict=Y=   3.7ms,len=   4.0ms,ch=   2079]  pymupdf=   3.4ms(   1999)  pdfminer.six= 126.9ms(   2283)  pdfplumber=  82.1ms(   1973)  
[ 19/67] eu-019.pdf: spectre[strict=Y=   5.2ms,len=   5.4ms,ch=   4193]  pymupdf=   5.9ms(   4099)  pdfminer.six= 117.9ms(   4452)  pdfplumber= 121.4ms(   4050)  
[ 20/67] eu-020.pdf: spectre[strict=Y=   5.9ms,len=   5.6ms,ch=   7171]  pymupdf=   5.3ms(   7053)  pdfminer.six= 120.0ms(   7454)  pdfplumber= 188.0ms(   6790)  
[ 21/67] eu-021.pdf: spectre[strict=Y=  10.2ms,len=  10.0ms,ch=   7920]  pymupdf=   6.6ms(   7428)  pdfminer.six= 265.0ms(   8094)  pdfplumber= 343.1ms(   7069)  
[ 22/67] eu-022.pdf: spectre[strict=Y=   4.0ms,len=   3.9ms,ch=   2261]  pymupdf=   2.9ms(   2172)  pdfminer.six=  61.1ms(   2280)  pdfplumber=  90.6ms(   2027)  
[ 23/67] eu-023.pdf: spectre[strict=Y=   4.3ms,len=   3.7ms,ch=   3553]  pymupdf=   3.3ms(   3471)  pdfminer.six=  75.8ms(   3670)  pdfplumber=  98.4ms(   3330)  
[ 24/67] eu-024.pdf: spectre[strict=Y=   3.4ms,len=   3.4ms,ch=   2669]  pymupdf=   2.7ms(   2602)  pdfminer.six=  53.6ms(   2803)  pdfplumber=  90.8ms(   2478)  
[ 25/67] eu-025.pdf: spectre[strict=Y=   5.3ms,len=   5.3ms,ch=   2467]  pymupdf=   4.1ms(   2139)  pdfminer.six= 162.4ms(   2465)  pdfplumber= 180.5ms(   1946)  
[ 26/67] eu-026.pdf: spectre[strict=Y=  11.4ms,len=  10.8ms,ch=  15783]  pymupdf=  19.1ms(  14933)  pdfminer.six= 385.5ms(  15128)  pdfplumber= 505.5ms(  14955)  
[ 27/67] eu-027.pdf: spectre[strict=Y=   6.7ms,len=   5.2ms,ch=   3724]  pymupdf=   9.6ms(   3987)  pdfminer.six= 146.4ms(   3991)  pdfplumber= 188.5ms(   3966)  
[ 28/67] us-001.pdf: spectre[strict=Y=   5.6ms,len=   5.4ms,ch=  12479]  pymupdf=   7.3ms(  13188)  pdfminer.six= 135.5ms(  13408)  pdfplumber= 230.3ms(  12627)  
[ 29/67] us-002.pdf: spectre[strict=Y=   3.8ms,len=   3.7ms,ch=   9467]  pymupdf=   4.5ms(   9531)  pdfminer.six= 101.3ms(   9691)  pdfplumber= 170.4ms(   9280)  
[ 30/67] us-003.pdf: spectre[strict=Y=   1.7ms,len=   1.8ms,ch=   3250]  pymupdf=   2.6ms(   3199)  pdfminer.six=  28.8ms(   3223)  pdfplumber=  52.3ms(   3089)  
[ 31/67] us-004.pdf: spectre[strict=Y=   1.9ms,len=   1.8ms,ch=   5416]  pymupdf=   2.8ms(   5490)  pdfminer.six=  54.1ms(   5834)  pdfplumber=  96.1ms(   5303)  
[ 32/67] us-005.pdf: spectre[strict=N=   1.2ms,len=   1.1ms,ch=      0]  pymupdf=   1.6ms(   2259)  pdfminer.six=  23.6ms(   2409)  pdfplumber=  35.1ms(   2226)  
MuPDF error: format error: cannot find object in xref (12 0 R)

MuPDF error: format error: cannot find object in xref (12 0 R)

MuPDF error: format error: cannot find object in xref (12 0 R)

MuPDF error: format error: cannot find object in xref (12 0 R)

[ 33/67] us-006.pdf: spectre[strict=Y=   5.3ms,len=   5.2ms,ch=  10556]  pymupdf=   6.0ms(  10383)  pdfminer.six= 116.7ms(  10427)  pdfplumber= 197.9ms(  10172)  
[ 34/67] us-007.pdf: spectre[strict=Y=  11.2ms,len=  10.7ms,ch=  10965]  pymupdf=   8.3ms(  10728)  pdfminer.six= 246.4ms(  10894)  pdfplumber= 386.7ms(  10019)  
MuPDF error: format error: cannot find object in xref (4 0 R)

MuPDF error: format error: cannot find object in xref (4 0 R)

MuPDF error: format error: cannot find object in xref (30 0 R)

MuPDF error: format error: cannot find object in xref (30 0 R)

MuPDF error: format error: cannot find object in xref (7 0 R)

MuPDF error: format error: cannot find object in xref (7 0 R)

MuPDF error: format error: cannot find object in xref (7 0 R)

MuPDF error: format error: cannot find object in xref (7 0 R)

MuPDF error: format error: cannot find object in xref (4 0 R)

MuPDF error: format error: cannot find object in xref (4 0 R)

MuPDF error: format error: cannot find object in xref (30 0 R)

MuPDF error: format error: cannot find object in xref (30 0 R)

MuPDF error: format error: cannot find object in xref (7 0 R)

MuPDF error: format error: cannot find object in xref (7 0 R)

MuPDF error: format error: cannot find object in xref (7 0 R)

MuPDF error: format error: cannot find object in xref (7 0 R)

[ 35/67] us-008.pdf: spectre[strict=Y=   5.0ms,len=   5.0ms,ch=   8156]  pymupdf=   5.6ms(   7995)  pdfminer.six=  94.2ms(   8075)  pdfplumber= 181.9ms(   7666)  
[ 36/67] us-009.pdf: spectre[strict=Y=   1.8ms,len=   2.0ms,ch=   3277]  pymupdf=   3.0ms(   3331)  pdfminer.six=  42.3ms(   3519)  pdfplumber=  64.9ms(   2329)  
[ 37/67] us-010.pdf: spectre[strict=N=   2.8ms,len=   3.5ms,ch=   1031]  pymupdf=   4.4ms(   6148)  pdfminer.six=  80.9ms(   6210)  pdfplumber= 135.3ms(   5995)  
[ 38/67] us-011a.pdf: spectre[strict=N=   2.5ms,len=   2.6ms,ch=      0]  pymupdf=   3.4ms(   2879)  pdfminer.six=  53.6ms(   2948)  pdfplumber=  94.4ms(   2715)  
[ 39/67] us-012.pdf: spectre[strict=Y=   2.5ms,len=   2.3ms,ch=   1759]  pymupdf=   2.3ms(   1829)  pdfminer.six=  56.9ms(   1959)  pdfplumber=  61.4ms(   1639)  
[ 40/67] us-013.pdf: spectre[strict=Y=   6.2ms,len=   6.2ms,ch=  10871]  pymupdf=   6.5ms(  10677)  pdfminer.six= 117.2ms(  10731)  pdfplumber= 211.6ms(  10306)  
[ 41/67] us-014.pdf: spectre[strict=Y=   5.7ms,len=   5.8ms,ch=   8920]  pymupdf=   6.1ms(   8723)  pdfminer.six= 105.5ms(   8784)  pdfplumber= 177.2ms(   8428)  
[ 42/67] us-015.pdf: spectre[strict=Y=   3.7ms,len=   3.5ms,ch=   9047]  pymupdf=   4.9ms(   8938)  pdfminer.six=  99.8ms(   9029)  pdfplumber= 157.1ms(   8638)  
[ 43/67] us-016.pdf: spectre[strict=Y=   3.0ms,len=   2.8ms,ch=   9433]  pymupdf=   4.3ms(   9386)  pdfminer.six=  83.2ms(   9441)  pdfplumber= 159.3ms(   9144)  
[ 44/67] us-017.pdf: spectre[strict=Y=   4.6ms,len=   4.9ms,ch=  16203]  pymupdf=   7.0ms(  17490)  pdfminer.six= 133.3ms(  17714)  pdfplumber= 280.1ms(  17285)  
[ 45/67] us-018.pdf: spectre[strict=Y=   5.0ms,len=   4.7ms,ch=  20091]  pymupdf=   5.9ms(  21536)  pdfminer.six= 191.9ms(  21757)  pdfplumber= 321.0ms(  21201)  
[ 46/67] us-019.pdf: spectre[strict=Y=   4.0ms,len=   3.6ms,ch=  12745]  pymupdf=   6.1ms(  13015)  pdfminer.six=  85.1ms(  13157)  pdfplumber= 214.4ms(  12937)  
[ 47/67] us-020.pdf: spectre[strict=Y=  12.7ms,len=  14.1ms,ch=  20656]  pymupdf=  10.5ms(  20446)  pdfminer.six= 281.7ms(  20691)  pdfplumber= 436.0ms(  20132)  
[ 48/67] us-021.pdf: spectre[strict=Y=   8.6ms,len=   7.8ms,ch=  13020]  pymupdf=   7.3ms(  12754)  pdfminer.six= 144.8ms(  12835)  pdfplumber= 265.7ms(  12539)  
[ 49/67] us-022.pdf: spectre[strict=Y=   4.2ms,len=   3.8ms,ch=   8244]  pymupdf=   4.5ms(   7245)  pdfminer.six=  77.8ms(   7436)  pdfplumber= 128.0ms(   6824)  
[ 50/67] us-023.pdf: spectre[strict=Y=   7.2ms,len=   7.1ms,ch=  17382]  pymupdf=   8.4ms(  17245)  pdfminer.six= 185.1ms(  18018)  pdfplumber= 296.1ms(  17026)  
[ 51/67] us-024.pdf: spectre[strict=Y=   7.0ms,len=   7.2ms,ch=  24438]  pymupdf=  10.8ms(  24765)  pdfminer.six= 590.4ms(  25836)  pdfplumber= 394.4ms(  24428)  
[ 52/67] us-025.pdf: spectre[strict=Y=   7.3ms,len=   6.7ms,ch=  22291]  pymupdf=   9.7ms(  22239)  pdfminer.six= 271.4ms(  22881)  pdfplumber= 355.8ms(  22031)  
[ 53/67] us-026.pdf: spectre[strict=Y=   2.7ms,len=   2.5ms,ch=   3048]  pymupdf=   2.3ms(   2885)  pdfminer.six=  66.7ms(   2901)  pdfplumber=  61.4ms(   2701)  
[ 54/67] us-027.pdf: spectre[strict=Y=   3.8ms,len=   3.8ms,ch=  14559]  pymupdf=   6.4ms(  14479)  pdfminer.six= 139.8ms(  14543)  pdfplumber= 265.7ms(  13944)  
[ 55/67] us-028.pdf: spectre[strict=Y=   4.5ms,len=   4.7ms,ch=  10096]  pymupdf=   5.4ms(  10078)  pdfminer.six= 141.9ms(  10275)  pdfplumber= 220.9ms(   9660)  
[ 56/67] us-029.pdf: spectre[strict=Y=   2.8ms,len=   3.2ms,ch=   7285]  pymupdf=   4.2ms(   7242)  pdfminer.six=  67.5ms(   7283)  pdfplumber= 145.3ms(   7074)  
[ 57/67] us-030.pdf: spectre[strict=Y=   5.1ms,len=   5.1ms,ch=   6697]  pymupdf=   4.2ms(   6461)  pdfminer.six=  84.2ms(   6530)  pdfplumber= 142.6ms(   6316)  
[ 58/67] us-031a.pdf: spectre[strict=Y=   5.8ms,len=   5.6ms,ch=   8181]  pymupdf=   4.9ms(   7979)  pdfminer.six= 106.9ms(   8033)  pdfplumber= 175.9ms(   7842)  
[ 59/67] us-032.pdf: spectre[strict=Y=   1.8ms,len=   1.2ms,ch=   2722]  pymupdf=   2.4ms(   2585)  pdfminer.six=  23.9ms(   2745)  pdfplumber=  55.8ms(   2515)  
[ 60/67] us-033.pdf: spectre[strict=Y=   1.6ms,len=   1.8ms,ch=   4021]  pymupdf=   2.4ms(   4176)  pdfminer.six=  33.8ms(   4321)  pdfplumber=  72.6ms(   4124)  
[ 61/67] us-034.pdf: spectre[strict=Y=   1.6ms,len=   1.4ms,ch=   5653]  pymupdf=   2.5ms(   5697)  pdfminer.six=  34.5ms(   5801)  pdfplumber=  88.2ms(   4951)  
[ 62/67] us-035a.pdf: spectre[strict=Y=   2.1ms,len=   2.0ms,ch=   4618]  pymupdf=   3.0ms(   4831)  pdfminer.six=  40.8ms(   4925)  pdfplumber=  81.1ms(   4795)  
[ 63/67] us-036.pdf: spectre[strict=Y=   4.2ms,len=   3.4ms,ch=   3969]  pymupdf=  12.7ms(   3919)  pdfminer.six=  49.4ms(   3969)  pdfplumber=  84.3ms(   3752)  
[ 64/67] us-037.pdf: spectre[strict=Y=   4.2ms,len=   3.8ms,ch=   2062]  pymupdf=   2.5ms(   1873)  pdfminer.six=  89.9ms(   1968)  pdfplumber=  96.3ms(   1373)  
[ 65/67] us-038.pdf: spectre[strict=Y=   1.6ms,len=   1.6ms,ch=  10700]  pymupdf=   3.3ms(  10733)  pdfminer.six=  70.3ms(  10791)  pdfplumber= 160.5ms(  10681)  
[ 66/67] us-039.pdf: spectre[strict=Y=   1.9ms,len=   1.4ms,ch=   8759]  pymupdf=   3.3ms(   8847)  pdfminer.six=  50.8ms(   8976)  pdfplumber= 141.9ms(   8879)  
[ 67/67] us-040.pdf: spectre[strict=Y=   5.3ms,len=   5.0ms,ch=  10623]  pymupdf=   4.3ms(  10011)  pdfminer.six= 176.4ms(  10147)  pdfplumber= 266.6ms(   9981)  

## Headline — Full ICDAR 2013 corpus, strict mode (67 unique PDFs)

spectre runs `extract_text` (strict): the 3 PDFs whose CID fonts omit `/ToUnicode` raise `ExtractError::PageExtractFailed`. The fail-time is included in spectre's total. pymupdf / pdfminer.six / pdfplumber silently produce output on the same documents (without surfacing the underlying parse failure) — see Correctness section below.

| Tool | Total time | Successful PDFs | vs spectre |
|---|---:|---:|---:|
| **spectre_rs** (`extract_text`, strict) | **  0.32 s** | 64/67 (3 raise, time-to-failure included) | **1.0x (baseline)** |
| pymupdf |   0.37 s | 67/67 |  1.17x |
| pdfminer.six |   8.45 s | 67/67 | 26.53x |
| pdfplumber |  12.89 s | 67/67 | 40.46x |

### Lenient-mode reference (silent-skip behaviour, matches Python tools)

spectre running `extract_text_lenient` (drops failing pages silently, matching pymupdf/pdfminer/pdfplumber's silent-skip behaviour). Provided so callers who explicitly want the established libraries' failure mode can see the comparison.

| Tool | Total time | vs spectre (lenient) |
|---|---:|---:|
| spectre_rs (lenient) |   0.31 s | 1.0x (baseline) |
| pymupdf |   0.37 s |  1.20x |
| pdfminer.six |   8.45 s | 26.99x |
| pdfplumber |  12.89 s | 41.17x |

## Char-count parity vs pymupdf

PDFs compared (both non-empty): 65/67
Mean delta (spectre / pymupdf - 1): -0.1%
Median delta: +0.6%
PDFs within +/-10%: 60/65

full per-PDF JSON: /tmp/spectre-bench/icdar2013_results.json
per-PDF CSV (committed in repo): /mnt/c/Users/RyanJ/spectre-rs/data/icdar2013-results.csv
