perf: replace pdfium global lock with process pool for concurrent rendering#494
Closed
KRRT7 wants to merge 1 commit into
Closed
perf: replace pdfium global lock with process pool for concurrent rendering#494KRRT7 wants to merge 1 commit into
KRRT7 wants to merge 1 commit into
Conversation
…dering
pypdfium2 is not thread-safe, so a global Lock serialized ALL PDF
rendering — concurrent documents queued behind each other. This replaces
the lock with a ProcessPoolExecutor (default: cpu_count/2 workers,
configurable via PDF_RENDER_POOL_SIZE). Each worker has its own pdfium
instance in a separate address space, enabling true parallel rendering.
Benchmark (loremipsum 10-page PDF, warmed pool):
Threads | Lock (old) | Pool (new) | Speedup
--------+------------+------------+--------
1 | 0.78s | 0.81s | 1.0x
4 | 4.56s | 1.66s | 2.7x
8 | 5.27s | 2.80s | 1.9x
Single-doc latency unchanged (~66ms/page).
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
threading.Lockaround pypdfium2 rendering with aProcessPoolExecutorcpu_count / 2, configurable viaPDF_RENDER_POOL_SIZEenv varconvert_pdf_to_imagepublic APIWhy
pypdfium2's C library is not thread-safe, so PR #458 added a global
_pdfium_lock = Lock()that serializes all PDF rendering. When multiple documents are processed concurrently (viaasyncio.to_threadin core-product), each one queues behind the others — destroying throughput.Benchmark
Rendering
loremipsum_multipage.pdf(10 pages, 200 DPI) with N concurrent threads:Single-document latency unchanged (~66ms/page after warmup).
Rendering accounts for 23-43% of total per-page pipeline time (depending on model inference speed), so this translates to meaningful end-to-end throughput gains under concurrency.
Benchmark script
Test plan
pytest test_unstructured_inference/ -x -q— 247 passed, 1 skipped)path_only=True(primary production path) and PIL image return