https://christina04.hatenablog.com/entry/fastapi-def-vs-async-def
Should FastAPI use def or async def for Path Operation?
background
In FastAPI, you can set the path of the HTTP server by using the decorator function as shown below, which is called Path Operation.
def
I will explain the policy of whether to use or should use in this Path Operation async def
.
environment
- Python 3.9.11
- FastAPI 0.74.1
policy
From the conclusion, let's implement it with the following policy.
await
async def
Use if there isdef
Use otherwise
cause
The reason is as follows.
- Even if it is CPU bound processing, it does not
async def
changedef
def
For IO bound in synchronous processing, it is better to use an external thread poolawait
Asynchronous processing isasync def
required
I will explain one by one.
FastAPI has a main async loop and an external thread pool
First of all, as a prerequisite, FastAPI has a main async loop and an external thread pool.
def
→ External thread poolasync def
→ Main a sync loop
Will be executed in.
The external thread pool looks multithreaded but is effectively single threaded
In the figure above, the external thread pool looks like multithreading.
However , Python uses the GIL (Global Interpreter Lock), which is an exclusive lock to prevent sharing unthread-safe code ( such as C language libraries) with other threads, so threads that can be executed at the same time . Is limited to one .
So there is no difference in CPU bound processing whether it is an external thread pool or a thread in the main async loop.
External thread pool can switch to another thread during synchronous IO
However, in the case of IO bound synchronization processing, it is advantageous to have multiple threads because it does not use the CPU and is simply blocked by waiting time.
In the main async loop, processing is blocked, so only three processes can be executed, whereas in an external thread pool with multiple threads, threads can be switched while waiting to process many requests .
await
In asynchronous processingasync def
await
Asynchronous processing with is async def
only usable within the first place.
You can only use await inside of functions created with async def.
ref: Concurrency and async / await --FastAPI
I think the following past articles will be helpful for distinguishing between synchronous and asynchronous.
Since the main async loop that was blocked earlier is an asynchronous IO, it is not blocked, and like a multithreaded synchronous IO, it will be in the next event during preparation, and when preparation is completed, processing of that event will be completed.
benchmark
Below are the actual benchmark results. From the left
def
Perform synchronization processing with- Asynchronous processing is
async def
executed by async def
Perform synchronization processing with
It has become.
You can see that the IO bound synchronization process is async def
blocked inside and the performance is poor as mentioned above .
On the other hand, in the following benchmarks , CPU-bound processing has async def
better performance .
Since the context switch occurs when switching threads, it seems that the performance was affected by that amount.
However, it is costly to implement and review to always be aware of which function is CPU bound, so basically it def
is better to give priority to the same level of performance.
summary
- If it is CPU bound processing, async def and def do not change much
- In case of IO bound in synchronous processing, def using external thread pool is excellent
- Async def is required for asynchronous processing with await
From that
- Use async def if you have await
- Otherwise use def
You should judge that.
0 件のコメント:
コメントを投稿