When Python Syntax Matters
Last year, when adopting FastAPI for use in production, I stumbled across an issue when sending larger payloads to my API.
What was taking ~1.8s in Flask was taking >10 minutes in FastAPI. Upon doing some sleuthing online, it turned out others were experiencing similar. Upon conferring with some of the other devs affected by this, I put together a quick example to demonstrate the performance hit.
Another user did some great digging and managed to isolate the problem to the Starlette library which FastAPI sits atop of. It turns out that Starlette was using the +=
syntax when processing the request body chunks. This caused a quadratic growth in the time complexity of the operation.
Once the Starlette library was fixed to use join()
, the issue was immediately resolved. It served a useful reminder that it pays to understand what happens under the hood for these sorts of operations.
To summarise:
+=
(concatenation):
- Creates a new string object each time
- O(n²) time complexity for n concatenations
- Each operation copies all previous characters
join()
method:
- Calculates total size first, allocates once
- O(n) time complexity
- Much more memory efficient
So if you're optimising for speed, use join()
unless you're only operating on a few short strings!