Heim >Backend-Entwicklung >Python-Tutorial >Warum ist meine Multithread-API immer noch langsam?
Ich habe ein Problem mit meiner API und hoffe, dass mir jemand helfen kann. Trotz der Hinzufügung von Multithreading liegen die Leistungssteigerungen weit hinter meinen Erwartungen zurück. Wenn ein Thread 1 Sekunde benötigt, um eine Aufgabe abzuschließen, sollten im Idealfall 10 Threads, die gleichzeitig ausgeführt werden, ebenfalls etwa 1 Sekunde dauern (so mein Verständnis). Allerdings sind meine API-Antwortzeiten immer noch sehr langsam.
Ich verwende FastAPI zusammen mit Bibliotheken wie Playwright, MongoDB und ThreadPoolExecutor. Das Ziel bestand darin, Threading für CPU-gebundene Aufgaben und Async-Await für IO-gebundene Aufgaben zu verwenden. Dennoch verbessern sich meine Reaktionszeiten nicht wie erwartet.
Ein Teil meines Projekts besteht darin, Buchabfragen mithilfe von Playwright zu automatisieren, um mit einem EPUB-Viewer zu interagieren. Die folgende Funktion verwendet Playwright, um einen Browser zu öffnen, zur Seite eines Buches zu navigieren und Suchvorgänge durchzuführen:
from playwright.async_api import async_playwright import asyncio async def search_with_playwright(search_text: str, book_id: str): async with async_playwright() as p: browser = await p.chromium.launch(headless=True) page = await browser.new_page() book_id = book_id.replace("-1", "") book_url = f"http://localhost:8002/book/{book_id}" await page.goto(book_url) await page.fill("#searchInput", search_text) await page.click("#searchButton") await page.wait_for_selector("#searchResults") search_results = await page.evaluate(''' () => { let results = []; document.querySelectorAll("#searchResults ul li").forEach(item => { let excerptElement = item.querySelector("strong:nth-of-type(1)"); let cfiElement = item.querySelector("strong:nth-of-type(2)"); if (excerptElement && cfiElement) { let excerpt = excerptElement.nextSibling ? excerptElement.nextSibling.nodeValue.trim() : ""; let cfi = cfiElement.nextSibling ? cfiElement.nextSibling.nodeValue.trim() : ""; results.push({ excerpt, cfi }); } }); return results; } ''') await browser.close() return search_results
Die obige Funktion soll asynchron sein, um das Blockieren anderer Aufgaben zu vermeiden. Allerdings ist die Leistung selbst mit diesem asynchronen Setup immer noch nicht wie erwartet.
Hinweis: Ich habe berechnet, dass es etwa 0,0028 Sekunden dauert, ein Buch zu öffnen und ein einzelnes Buch abzufragen
Ich habe run_in_executor() verwendet, um Funktionen in ProcessPoolExecutor auszuführen und dabei versucht, die GIL zu vermeiden und Arbeitslasten richtig zu verwalten.
async def query_mongo(query: str, id: str): query_vector = generate_embedding(query) results = db[id].aggregate([ { "$vectorSearch": { "queryVector": query_vector, "path": "embedding", "numCandidates": 2100, "limit": 50, "index": id } } ]) # Helper function for processing each document def process_document(document): try: chunk = document["chunk"] chapter = document["chapter"] number = document["chapter_number"] book_id = id results = asyncio.run(search_with_playwright(chunk, book_id)) return { "content": chunk, "chapter": chapter, "number": number, "results": results, } except Exception as e: print(f"Error processing document: {e}") return None # Using ThreadPoolExecutor for concurrency all_data = [] with ThreadPoolExecutor() as executor: futures = {executor.submit(process_document, doc): doc for doc in results} for future in as_completed(futures): try: result = future.result() if result: # Append result if it's not None all_data.append(result) except Exception as e: print(f"Error in future processing: {e}") return all_data
Selbst nach diesen Änderungen ist meine API immer noch langsam. Was fehlt mir? Hat jemand ähnliche Probleme mit Pythons GIL-, Threading- oder asynchronen Setups gehabt? Für jeden Rat wäre ich sehr dankbar!
Das obige ist der detaillierte Inhalt vonWarum ist meine Multithread-API immer noch langsam?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!