`created_cloned_field` — slow performance with many models
See original GitHub issueFirst Check
- I added a very descriptive title to this issue.
- I used the GitHub search to find a similar issue and didn’t find it.
- I searched the FastAPI documentation, with the integrated search.
- I already searched in Google “How to X in FastAPI” and didn’t find any information.
- I already read and followed all the tutorial in the docs and didn’t find an answer.
- I already checked if it is not related to FastAPI but to Pydantic.
- I already checked if it is not related to FastAPI but to Swagger UI.
- I already checked if it is not related to FastAPI but to ReDoc.
Commit to Help
- I commit to help with one of those options 👆
Example Code
import fastapi
import pydantic
class NestedModel(pydantic.BaseModel):
x: pydantic.BaseModel
y: pydantic.BaseModel
def create_app():
for _ in range(100):
fastapi.routing.APIRoute(
"/test", endpoint=lambda: ..., response_model=NestedModel
)
# PROFILING
import yappi
yappi.set_clock_type("CPU")
with yappi.run():
create_app()
stats = yappi.get_func_stats()
stats.save("fastapi.pprof", type="pstat")
Description
When building a FastAPI application with nested Pydantic models, the create_cloned_field
utility in the APIRoute
initialization is quite slow.
For the trivial example, you can see that create_cloned_field
dominates the runtime with 90% of CPU time. The majority of this is spent deep copying.
Note, timing is CPU time not WALL time
If we replace this trivial application with the one from Prefect, from prefect.orion.api.server import create_app
, we can see that this is significant in a real world example.
With a patch to retain the cache across calls to this function, we can get this down to 50% of the CPU time with a ~5x overall speedup.
This speedup persists and is even more significant in a real-world application with create_cloned_field
accounting for only 11% of the CPU time.
Operating System
macOS
Operating System Details
No response
FastAPI Version
0.74.0
Python Version
3.8.12
Additional Context
This may also be resolvable with https://github.com/samuelcolvin/pydantic/issues/1008 as mentioned in https://github.com/tiangolo/fastapi/issues/894#issuecomment-576484427
Issue Analytics
- State:
- Created 2 years ago
- Reactions:14
- Comments:10 (1 by maintainers)
Top GitHub Comments
We are currently using a monkey patched version of the normal
main.py
like this:Note that the docs at the top only fit our own setup with running everything in docker and note that I did remove the app name (replaced by “something”).
Anyways this seems to work for us now and we do not have any issues. I cannot reproduce the problems we had any more. RAM usage is still also down by a huge amount.
Nice thing about this additional file + the monkey patch is that we still can just build a normal production version that does include this.
Any update on this?