API で問題に直面しています。誰かが助けてくれることを願っています。マルチスレッドを追加したにもかかわらず、パフォーマンスの向上は私が期待していたものとは程遠いものでした。理想的には、1 つのスレッドがタスクを完了するのに 1 秒かかる場合、同時に実行されている 10 個のスレッドも約 1 秒かかるはずです (これが私の理解です)。ただし、API の応答時間は依然として非常に遅いです。
私は、Playwright、MongoDB、ThreadPoolExecutor などのライブラリとともに FastAPI を使用しています。目標は、CPU バウンドのタスクにはスレッドを使用し、IO バウンドのタスクには async-await を使用することでした。それでも、応答時間は期待したほど改善されていません。
私のプロジェクトの一部には、Playwright を使用して EPUB ビューアと対話する書籍クエリの自動化が含まれます。次の関数は、Playwright を使用してブラウザーを開き、書籍のページに移動し、検索を実行します。
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
上記の関数は、他のタスクのブロックを避けるために非同期であることを目的としています。ただし、この非同期設定を行っても、パフォーマンスは依然として期待どおりではありません。
注: ブックを開いてクエリを実行するのにかかる時間は、1 冊のブックで約 0.0028 秒であると計算しました
GIL を回避してワークロードを適切に管理するために、run_in_executor() を使用して ProcessPoolExecutor の関数を実行しました。
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
これらの変更後でも、私の API は依然として遅いです。私には何が欠けているのでしょうか? Python の GIL、スレッド、または非同期セットアップで同様の問題に直面した人はいますか?アドバイスをいただければ幸いです!
以上がマルチスレッド API が依然として遅いのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。