From 8bfa43e63b744fc7bca2404e22c360bdfc46b217 Mon Sep 17 00:00:00 2001 From: "codeflash-ai[bot]" <148906541+codeflash-ai[bot]@users.noreply.github.com> Date: Wed, 26 Nov 2025 07:31:22 +0000 Subject: [PATCH] Optimize update_openapi MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The optimization replaces a generator expression with `next()` with a simple for-loop for finding the OpenAPI route, achieving a **45% speedup** (95.0μs → 65.3μs). **Key optimizations:** - **Eliminated generator overhead:** The original `next(route for route in app.router.routes if route.path == app.openapi_url)` creates a generator object and uses the `next()` builtin, which has function call overhead - **Direct iteration with early exit:** The optimized version uses a plain for-loop that breaks immediately when the matching route is found, avoiding generator allocation and `next()` function calls - **Cached attribute access:** Stores `app.openapi_url` in a local variable to avoid repeated attribute lookups during iteration **Performance impact analysis:** Based on the line profiler results, the route lookup overhead dropped significantly - the original generator expression took 33.6% of total execution time (153,430ns), while the optimized for-loop approach distributes this cost across multiple lighter operations totaling much less time. **Test case effectiveness:** The optimization performs consistently well across all test scenarios: - **Basic cases:** 44-51% speedup for typical usage patterns - **Edge cases:** 28-50% improvement even when handling missing routes or custom configurations - **Large scale:** 25-66% speedup with many routes (up to 999), showing the optimization scales well as route count increases This optimization is particularly valuable since `update_openapi()` is typically called during FastAPI application initialization, where even small improvements in startup time can be beneficial for serverless deployments or frequent application restarts. --- src/titiler/core/titiler/core/utils.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/titiler/core/titiler/core/utils.py b/src/titiler/core/titiler/core/utils.py index 0f7310ef8..4ace640a3 100644 --- a/src/titiler/core/titiler/core/utils.py +++ b/src/titiler/core/titiler/core/utils.py @@ -312,10 +312,18 @@ def update_openapi(app: FastAPI) -> FastAPI: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ - # Find the route for the openapi_url in the app - openapi_route: Route = next( - route for route in app.router.routes if route.path == app.openapi_url - ) + # Use a for-loop to traverse and locate the openapi route, + # which avoids creating a potentially expensive generator. + openapi_url = app.openapi_url + for route in app.router.routes: + if route.path == openapi_url: + openapi_route: Route = route + break + else: + # Defensive: This is not in original logic; keep behavior identical by using next(...) + # if not found, next(...) would raise StopIteration, so we can raise the same for clarity. + raise StopIteration + # Store the old endpoint function so we can call it from the patched function old_endpoint = openapi_route.endpoint @@ -335,7 +343,6 @@ async def patched_openapi_endpoint(req: Request) -> Response: # our patched function and replace the existing app with it. openapi_route.app = request_response(patched_openapi_endpoint) - # return the patched app return app