Skip to content

perf(writer): replace recursive reachable-ref walk with iterative stack#52

Merged
Mythie merged 1 commit intomainfrom
perf/iterative-reachable-refs
Mar 11, 2026
Merged

perf(writer): replace recursive reachable-ref walk with iterative stack#52
Mythie merged 1 commit intomainfrom
perf/iterative-reachable-refs

Conversation

@Mythie
Copy link
Contributor

@Mythie Mythie commented Mar 11, 2026

Avoids potential stack overflow on deeply nested object graphs,
consistent with the fix in 6db670a.

Avoids potential stack overflow on deeply nested object graphs,
consistent with the fix in 6db670a.
@vercel
Copy link
Contributor

vercel bot commented Mar 11, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
core Ready Ready Preview, Comment Mar 11, 2026 8:10am

@github-actions
Copy link
Contributor

Benchmark Results

Comparison

Load PDF

Benchmark Mean p99 RME Samples
libpdf 2.19ms 2.93ms ±1.1% 229
pdf-lib 39.48ms 44.39ms ±4.5% 13
@cantoo/pdf-lib 38.80ms 42.59ms ±2.4% 13

Create blank PDF

Benchmark Mean p99 RME Samples
libpdf 56μs 114μs ±1.4% 8856
pdf-lib 432μs 1.55ms ±3.1% 1157
@cantoo/pdf-lib 425μs 1.52ms ±2.5% 1178

Add 10 pages

Benchmark Mean p99 RME Samples
libpdf 99μs 159μs ±1.0% 5054
pdf-lib 507μs 1.84ms ±2.6% 987
@cantoo/pdf-lib 470μs 2.12ms ±3.0% 1065

Draw 50 rectangles

Benchmark Mean p99 RME Samples
libpdf 311μs 738μs ±1.3% 1606
pdf-lib 1.74ms 7.39ms ±7.4% 289
@cantoo/pdf-lib 1.83ms 4.45ms ±4.5% 273

Load and save PDF

Benchmark Mean p99 RME Samples
libpdf 2.25ms 2.94ms ±1.4% 222
pdf-lib 89.75ms 102.09ms ±5.6% 10
@cantoo/pdf-lib 154.78ms 163.02ms ±2.1% 10

Load, modify, and save PDF

Benchmark Mean p99 RME Samples
libpdf 42.36ms 55.56ms ±7.4% 12
pdf-lib 85.32ms 93.31ms ±4.0% 10
@cantoo/pdf-lib 151.66ms 155.69ms ±0.9% 10

Extract single page from 100-page PDF

Benchmark Mean p99 RME Samples
libpdf 3.68ms 5.88ms ±1.8% 136
pdf-lib 9.11ms 11.66ms ±1.8% 55
@cantoo/pdf-lib 9.76ms 11.99ms ±2.6% 52

Split 100-page PDF into single-page PDFs

Benchmark Mean p99 RME Samples
libpdf 32.76ms 38.31ms ±3.2% 16
pdf-lib 88.85ms 94.51ms ±4.0% 6
@cantoo/pdf-lib 101.33ms 119.21ms ±9.7% 6

Split 2000-page PDF into single-page PDFs (0.9MB)

Benchmark Mean p99 RME Samples
libpdf 614.72ms 614.72ms ±0.0% 1
pdf-lib 1.63s 1.63s ±0.0% 1
@cantoo/pdf-lib 1.70s 1.70s ±0.0% 1

Copy 10 pages between documents

Benchmark Mean p99 RME Samples
libpdf 4.94ms 8.10ms ±3.7% 102
pdf-lib 12.30ms 15.30ms ±2.5% 41
@cantoo/pdf-lib 13.48ms 16.38ms ±2.3% 38

Merge 2 x 100-page PDFs

Benchmark Mean p99 RME Samples
libpdf 14.34ms 19.09ms ±2.4% 35
pdf-lib 55.74ms 71.18ms ±8.4% 9
@cantoo/pdf-lib 62.88ms 65.95ms ±3.2% 8

Fill FINTRAC form fields

Benchmark Mean p99 RME Samples
libpdf 20.94ms 25.92ms ±4.3% 24
pdf-lib 34.31ms 50.69ms ±7.8% 15
@cantoo/pdf-lib 34.66ms 41.33ms ±4.6% 15

Fill and flatten FINTRAC form

Benchmark Mean p99 RME Samples
libpdf 19.25ms 24.23ms ±4.5% 26
pdf-lib FAILED - - 0
@cantoo/pdf-lib 38.97ms 44.17ms ±3.4% 13
Copying

Copy pages between documents

Benchmark Mean p99 RME Samples
copy 1 page 950μs 1.84ms ±2.2% 527
copy 10 pages from 100-page PDF 4.46ms 6.44ms ±2.0% 113
copy all 100 pages 7.20ms 8.14ms ±1.0% 70

Duplicate pages within same document

Benchmark Mean p99 RME Samples
duplicate page 0 864μs 1.59ms ±1.2% 579
duplicate all pages (double the document) 857μs 1.56ms ±1.1% 584

Merge PDFs

Benchmark Mean p99 RME Samples
merge 2 small PDFs 1.42ms 2.66ms ±1.3% 353
merge 10 small PDFs 7.23ms 9.27ms ±1.2% 70
merge 2 x 100-page PDFs 13.26ms 13.99ms ±0.8% 38
Drawing

benchmarks/drawing.bench.ts

Benchmark Mean p99 RME Samples
draw 100 rectangles 583μs 1.49ms ±2.5% 858
draw 100 circles 1.28ms 3.02ms ±2.6% 390
draw 100 lines 511μs 1.18ms ±1.5% 979
draw 100 text lines (standard font) 1.57ms 2.26ms ±1.2% 320
create 10 pages with mixed content 1.33ms 2.28ms ±1.7% 376
Forms

benchmarks/forms.bench.ts

Benchmark Mean p99 RME Samples
get form fields 3.19ms 6.08ms ±3.1% 157
fill text fields 11.82ms 16.52ms ±4.4% 43
read field values 2.89ms 4.13ms ±1.2% 173
flatten form 8.21ms 11.83ms ±2.8% 61
Loading

benchmarks/loading.bench.ts

Benchmark Mean p99 RME Samples
load small PDF (888B) 58μs 151μs ±0.7% 8601
load medium PDF (19KB) 91μs 182μs ±0.6% 5482
load form PDF (116KB) 1.37ms 2.60ms ±2.3% 364
load heavy PDF (9.9MB) 2.22ms 2.67ms ±0.6% 226
Saving

benchmarks/saving.bench.ts

Benchmark Mean p99 RME Samples
save unmodified (19KB) 106μs 251μs ±0.9% 4701
save with modifications (19KB) 743μs 1.35ms ±1.1% 674
incremental save (19KB) 160μs 336μs ±0.9% 3123
save heavy PDF (9.9MB) 2.18ms 2.69ms ±0.6% 230
incremental save heavy PDF (9.9MB) 8.49ms 9.97ms ±3.1% 59
Splitting

Extract single page

Benchmark Mean p99 RME Samples
extractPages (1 page from small PDF) 997μs 2.16ms ±2.9% 502
extractPages (1 page from 100-page PDF) 3.54ms 5.03ms ±1.1% 142
extractPages (1 page from 2000-page PDF) 56.02ms 57.53ms ±1.1% 10

Split into single-page PDFs

Benchmark Mean p99 RME Samples
split 100-page PDF (0.1MB) 31.26ms 35.87ms ±3.1% 16
split 2000-page PDF (0.9MB) 583.49ms 583.49ms ±0.0% 1

Batch page extraction

Benchmark Mean p99 RME Samples
extract first 10 pages from 2000-page PDF 57.71ms 60.89ms ±1.7% 9
extract first 100 pages from 2000-page PDF 61.15ms 63.69ms ±1.8% 9
extract every 10th page from 2000-page PDF (200 pages) 65.64ms 66.86ms ±1.3% 8
Environment
  • Runner: Linux (X64)
  • Runtime: Bun 1.3.10

Results are machine-dependent.

@Mythie Mythie merged commit 5e06df3 into main Mar 11, 2026
6 checks passed
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.

1 participant