Warum ist eine synchrone SQLAlchemy-Sitzung in FastAPI schneller als eine asynchrone?Python

Python-Programme
Anonymous
 Warum ist eine synchrone SQLAlchemy-Sitzung in FastAPI schneller als eine asynchrone?

Post by Anonymous »

Ich arbeite mit zwei Versionen einer FastAPI-Anwendung: eine mit einer asynchronen Verbindung zu einer SQLAlchemy-Datenbank und die andere mit einer synchronen Verbindung. Überraschenderweise beobachte ich, dass die synchrone Version bei Leistungstests die asynchrone deutlich übertrifft.
Setup:
  • FastAPI-Version: 0.95.1
  • SQLAlchemy-Version: 2.0.19
  • Datenbank: SQLite
  • PyNest-Version: 0.1.0
Leistungstestergebnisse:
  • Asynchrone Version: ~500 Sekunden für 1000 Anfragen
  • Synchronische Version: 0,72 Sekunden für 1000 Anfragen
Asynchrone Sitzungsinitialisierung:

Code: Select all

class Config:

def __init__(self):
self.engine = create_async_engine("sqlite+aiosqlite:///finance.db", connect_args={"check_same_thread": False})
self.SessionLocal = async_sessionmaker(self.engine)
self.Base = Base

async def create_all(self):
async with self.engine.begin() as conn:
await conn.run_sync(self.Base.metadata.create_all)

async def drop_all(self):
async with self.engine.begin() as conn:
await conn.run_sync(self.Base.metadata.drop_all)

async def get_db(self):
db = self.SessionLocal()
try:
yield db
finally:
await db.close()
Synchrone Sitzungsinitialisierung:

Code: Select all

class OrmService:
def __init__(self, db_type: str = "postgresql", config_params: dict = None):
self.Base = declarative_base()
self.config = ConfigFactory(db_type=db_type).get_config()
self.config_url = self.config(**config_params).get_engine_url()
self.engine = create_engine(self.config_url)

def create_all(self):
self.Base.metadata.create_all(bind=self.engine)

def drop_all(self):
self.Base.metadata.drop_all(bind=self.engine)

def get_db(self) -> Session:
try:
session = sessionmaker(bind=self.engine)
return session()
except Exception as e:
raise e
Controller und Dienst für die Async-Version:

Code: Select all

@Controller("finance")
class FinanceController:

@Get("/transactions")
async def get_transactions(self, session: AsyncSession = Depends(config.get_db)):
stmt = select(Transaction)
query = await session.execute(stmt)
return query.scalars().all()
Controller und Dienst für Sync-Version:

Code: Select all

@Controller("transaction", prefix="transaction")
class TransactionController:
service: TransactionService = Depends(TransactionService)

@Get("/")
def get_transactions(self):
return self.service.get_transactions()

@lru_cache()
class TransactionService:
def __init__(self):
self.orm_config = config
self.session = self.orm_config.get_db()

def get_transactions(self):
return self.session.query(TransactionEntity).first()
Testverfahren:
Ich verwende das folgende Testskript, um 1000 Anfragen an beide Versionen zu senden:

Code: Select all

import asyncio
import aiohttp
import time

async def fetch(session, url):
start_time = time.time()
async with session.get(url) as response:
response_text = await response.text()
end_time = time.time()
print(f"URL: {url} - Start: {start_time:.2f}, End: {end_time:.2f}, Duration: {end_time - start_time:.2f} seconds")
return response_text

async def main():
s = time.time()
urls = ["http://0.0.0.0:8088/transactions"] * 1000
async with aiohttp.ClientSession() as session:
tasks = [fetch(session, url) for url in urls]
responses = await asyncio.gather(*tasks)
print(len(responses))
print("response have been gathered")
print(f"Total time: {time.time() - s:.2f}")

# Run the main coroutine
asyncio.run(main())
Frage:
Ich bin verwirrt über den großen Leistungsunterschied zwischen den beiden Versionen. Die asynchrone Version, von der ich eine schnellere oder zumindest vergleichbare Leistung erwartet hatte, ist deutlich langsamer. Was könnte die Ursache für einen solchen Leistungsunterschied zwischen der synchronen und der asynchronen Version derselben Anwendung sein?
Alle Erkenntnisse oder Vorschläge dazu, was zu diesem Problem beitragen könnte und wie die asynchrone Version optimiert werden kann, wären sehr willkommen.

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post