0

0

为什么我的多线程 API 仍然很慢?

心靈之曲

心靈之曲

发布时间:2024-12-07 08:51:35

|

1101人浏览过

|

来源于dev.to

转载

为什么我的多线程 api 仍然很慢?

我的 api 遇到问题,希望有人可以提供帮助。尽管添加了多线程,但性能提升远没有达到我的预期。理想情况下,如果一个线程需要 1 秒来完成一项任务,那么并发运行的 10 个线程也应该需要大约 1 秒(这是我的理解)。然而,我的 api 响应时间仍然很慢。

问题

我正在使用 fastapi 以及 playwright、mongodb 和 threadpoolexecutor 等库。目标是对 cpu 密集型任务使用线程,对 io 密集型任务使用异步等待。尽管如此,我的响应时间并没有像预期的那样改善。

书籍自动化示例

我的项目的一部分涉及使用 playwright 与 epub 查看器交互来自动进行图书查询。以下函数使用 playwright 打开浏览器、导航到书籍页面并执行搜索:

TayCMS免费企业建站系统1.8 for PHP
TayCMS免费企业建站系统1.8 for PHP

由于精力有限,程序更新比较慢,请大家谅解,再次感谢支持taycms的朋友们,虽然比较慢,我们还是会一直更新下去的。谢谢您的关注。有什么建议可以到论坛提出,或者直接给我QQ留言。 2.0会有很多新功能,请关注官方论坛TayCMS 1.8 升级日志此版本修复了不少BUG1.更换图片切换JS , 不会再有错误提示2.增加资料下载模块3.更换默认模版,使程序功能和页面结构更清晰,方便参考制作模版4.修复留

下载
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.0028s

重构示例

我使用 run_in_executor() 来执行 processpoolexecutor 中的函数,试图避免 gil 并正确管理工作负载。

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、线程或异步设置方面遇到过类似的问题?任何建议将不胜感激!

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
Python FastAPI异步API开发_Python怎么用FastAPI构建异步API
Python FastAPI异步API开发_Python怎么用FastAPI构建异步API

Python FastAPI 异步开发利用 async/await 关键字,通过定义异步视图函数、使用异步数据库库 (如 databases)、异步 HTTP 客户端 (如 httpx),并结合后台任务队列(如 Celery)和异步依赖项,实现高效的 I/O 密集型 API,显著提升吞吐量和响应速度,尤其适用于处理数据库查询、网络请求等耗时操作,无需阻塞主线程。

27

2025.12.22

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

525

2023.08.10

Python 多线程与异步编程实战
Python 多线程与异步编程实战

本专题系统讲解 Python 多线程与异步编程的核心概念与实战技巧,包括 threading 模块基础、线程同步机制、GIL 原理、asyncio 异步任务管理、协程与事件循环、任务调度与异常处理。通过实战示例,帮助学习者掌握 如何构建高性能、多任务并发的 Python 应用。

189

2025.12.24

java多线程相关教程合集
java多线程相关教程合集

本专题整合了java多线程相关教程,阅读专题下面的文章了解更多详细内容。

19

2026.01.21

C++多线程相关合集
C++多线程相关合集

本专题整合了C++多线程相关教程,阅读专题下面的的文章了解更多详细内容。

19

2026.01.21

mongodb和mysql的区别
mongodb和mysql的区别

mongodb和mysql的区别:1、数据模型;2、查询语言;3、扩展性和性能;4、可靠性。本专题为大家提供mongodb和mysql的区别的相关的文章、下载、课程内容,供大家免费下载体验。

281

2023.07.18

mongodb启动命令
mongodb启动命令

MongoDB 是一种开源的、基于文档的 NoSQL 数据库管理系统。本专题提供mongodb启动命令的文章,希望可以帮到大家。

257

2023.08.08

MongoDB删除数据的方法
MongoDB删除数据的方法

MongoDB删除数据的方法有删除集合中的文档、删除整个集合、删除数据库和删除指定字段等。本专题为大家提供MongoDB相关的文章、下载、课程内容,供大家免费下载体验。

160

2023.09.19

2026赚钱平台入口大全
2026赚钱平台入口大全

2026年最新赚钱平台入口汇总,涵盖任务众包、内容创作、电商运营、技能变现等多类正规渠道,助你轻松开启副业增收之路。阅读专题下面的文章了解更多详细内容。

54

2026.01.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 22.4万人学习

Django 教程
Django 教程

共28课时 | 3.7万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号