接下來這幾天,會花點時間介紹 Python 的基礎知識,等大家都具備「同步/非同步」與「程序/執行緒 (process/thread)」的觀念後,再來向大家說明 def 與 async def 之間的差異。讓我們先從「同步/非同步」這個路線開始吧!
在開始深入 FastAPI 的世界之前,我們必須先理解一個核心的概念:同步與非同步程式設計。這不僅是理解 FastAPI 高效能特性的基礎,更是在 AI 服務開發中實現高併發處理的關鍵知識。
想像一下,當你的 AI 模型需要同時處理數百個影像辨識請求時,如果採用傳統的同步方式,每個請求都需要等待前一個完成,這將造成巨大的延遲。而非同步程式設計則能讓我們在等待一個模型推理的同時,開始處理下一個請求,大幅提升整體效能。
同步程式設計是我們最熟悉的程式執行方式,具有以下特性:
import time
def process_image_sync(image_id):
print(f"開始處理圖像 {image_id}")
time.sleep(2) # 模擬 AI 模型推理需要 2 秒
print(f"圖像 {image_id} 處理完成")
return f"result_{image_id}"
def main_sync():
start_time = time.time()
# 依序處理三張圖像
result1 = process_image_sync(1)
result2 = process_image_sync(2)
result3 = process_image_sync(3)
end_time = time.time()
print(f"總處理時間:{end_time - start_time:.2f} 秒")
print(f"處理結果:{[result1, result2, result3]}")
# 執行結果:總共需要 6 秒
main_sync()
在 AI 服務中,同步處理有幾個明顯的限制:
非同步程式設計改變了程式執行的根本方式:
import asyncio
import time
async def process_image_async(image_id):
print(f"開始處理圖像 {image_id}")
await asyncio.sleep(2) # 模擬非同步 AI 模型推理
print(f"圖像 {image_id} 處理完成")
return f"result_{image_id}"
async def main_async():
start_time = time.time()
# 並行處理三張圖像
tasks = [
process_image_async(1),
process_image_async(2),
process_image_async(3)
]
results = await asyncio.gather(*tasks)
end_time = time.time()
print(f"總處理時間:{end_time - start_time:.2f} 秒")
print(f"處理結果:{results}")
# 執行結果:總共只需要 2 秒
asyncio.run(main_async())
為了更好地理解這兩種模式,讓我們用生活中的例子來類比:
想像你要買手搖杯和隔壁的紅豆餅:
換個做法:
同步與非同步程式設計代表了兩種不同的思維方式。同步注重順序與確定性,非同步追求效率與並行。在 AI 服務的世界中,非同步程式設計能夠幫我們:
理解了這些基礎概念後,我們就準備好深入探索 FastAPI 的非同步世界了。在下一篇文章中,我們將學習協程(Coroutine)與事件迴圈(Event Loop)的具體實作,這是 Python 非同步程式設計的核心機制。