perf: lazy page rendering in convert_pdf_to_image#498
Merged
Conversation
Move from document-level locking to per-page locking: acquire _pdfium_lock only for pdfium operations (page load, render, bitmap conversion, close), release it before saving images to disk. This preserves the O(1) memory benefit for path_only=True (render, save, discard per page) while fixing the concurrency regression where PNG compression and filesystem writes held the global pdfium lock. Add tests for path_only=True hot path and a lock-scope regression test.
Two threads call convert_pdf_to_image with a deliberately slow save(). Verifies that disk writes can overlap rather than being serialized behind _pdfium_lock.
… error-isolation tests - Replace broken Event-based concurrency test with a Barrier that correctly detects whether two threads are inside save() simultaneously. - Add test that thread B can render while thread A is blocked in save(). - Add test that two threads produce all 10 pages from a multi-page PDF. - Add test that a failure in one thread does not block or poison the other.
badGarnet
approved these changes
Mar 27, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
path_only=True, images are no longer retained after saving to diskPeak memory drops from O(N pages) to O(1 page).
Benchmark
Azure Standard_D8s_v5 — 8 vCPU Intel Xeon Platinum 8473C, 32 GiB RAM, Python 3.12.12
50-page PDF (
sample-docs/pdf2image-memory-error-test-400p.pdf, first 50 pages), rendered at 200 DPI withoutput_folder:Memory (peak per test)
6a085c621f1c(base)692f6a17840b(head)Peak memory drops 174 MiB (-70%) by rendering and saving each page inside the loop instead of accumulating all PIL images before writing. Timing is neutral (+2% within noise).
Timing — convert_pdf_to_image (output_folder path, 50 pages)
6a085c621f1c(base)692f6a17840b(head)End-to-end pipeline benchmark (10 PDFs, 2,905 total pages)
Generated by codeflash optimization agent
Reproduce the benchmark locally
Benchmark test source
Test plan
convert_pdf_to_imagecovering the no-output-folder and output-folder-with-images return pathscodeflash compareconfirms -70% peak memory (248.7 MiB -> 74.8 MiB) on 50-page PDF