API에 문제가 있습니다. 누군가 도움을 줄 수 있기를 바랍니다. 멀티스레딩을 추가했음에도 불구하고 성능 향상은 기대했던 것과는 거리가 멀었습니다. 이상적으로는 하나의 스레드가 작업을 완료하는 데 1초가 걸리면 동시에 실행되는 10개의 스레드도 약 1초가 걸립니다(제가 이해한 바입니다). 하지만 내 API 응답 시간은 여전히 매우 느립니다.
저는 Playwright, MongoDB, ThreadPoolExecutor 같은 라이브러리와 함께 FastAPI를 사용하고 있습니다. 목표는 CPU 바인딩 작업에는 스레딩을 사용하고 IO 바인딩 작업에는 async-await를 사용하는 것이었습니다. 그래도 응답 시간이 예상만큼 개선되지 않습니다.
내 프로젝트의 한 부분은 EPUB 뷰어와 상호작용하기 위해 Playwright를 사용하여 도서 검색을 자동화하는 것입니다. 다음 기능은 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
위 기능은 다른 작업을 차단하지 않도록 비동기식으로 사용됩니다. 하지만 이런 비동기 설정에도 불구하고 성능은 여전히 기대에 미치지 못합니다.
참고: 책 한 권을 열고 쿼리를 실행하는 데 걸리는 시간을 계산해 보니 약 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!