diff --git a/.jules/bolt.md b/.jules/bolt.md index 1d2f017a..fde21932 100644 --- a/.jules/bolt.md +++ b/.jules/bolt.md @@ -63,3 +63,7 @@ ## 2024-07-30 - Avoid chained string replace when checking character sets **Learning:** Using chained `.replace(a, "").replace(b, "")` to check if a string consists entirely of specific characters requires intermediate string allocations for every call. In benchmarks, using `.strip("ab")` is ~30% faster and avoids multiple allocations in the hot path. **Action:** When checking if a string is solely composed of specific characters, use `.strip(chars)` instead of chained `.replace()` calls to improve performance. + +## 2024-08-01 - Performance Optimization: Increase Async File Read Chunk Size +**Learning:** In FastAPI, reading large file uploads with a small chunk size (e.g., 8KB) via `await file.read(8192)` causes excessive asynchronous event loop iterations and thread-dispatch overhead due to `SpooledTemporaryFile` mechanics. +**Action:** Increasing the chunk size (e.g., to 1MB: `await file.read(1024 * 1024)`) significantly reduces overhead and improves I/O performance for large uploads without sacrificing readability. diff --git a/src/newsdom_api/main.py b/src/newsdom_api/main.py index 4efdad56..57c8b9de 100644 --- a/src/newsdom_api/main.py +++ b/src/newsdom_api/main.py @@ -250,7 +250,9 @@ async def parse( tmp.write(header) bytes_read = len(header) - while chunk := await file.read(8192): + # ⚡ Bolt: Increase chunk size to 1MB to reduce async event loop iterations + # and thread-dispatch overhead for large PDF uploads. + while chunk := await file.read(1024 * 1024): bytes_read += len(chunk) if bytes_read > MAX_PARSE_UPLOAD_BYTES: LOGGER.warning(