异步编程中的性能优化技巧

异步编程中的性能优化技巧

在上一篇文章中,我们详细介绍了Python中的异步编程及其基础知识和实战应用。今天,我们将深入探讨异步编程中的性能优化技巧,帮助你进一步提升异步代码的效率。

  • 异步编程中的性能优化技巧
  • 结语

异步编程中的常见性能问题

在异步编程中,性能瓶颈主要出现在以下几个方面:

  • 过多的上下文切换:频繁的上下文切换会导致性能下降;
  • 阻塞操作:不当的阻塞操作会影响异步代码的效率;
  • 任务调度:任务调度不当会导致任务延迟和资源浪费。
使用asyncio提供的工具进行性能分析

Python的asyncio库提供了一些工具,可以帮助我们分析和优化异步代码的性能:

import asyncio
import time

async def slow_task():
    await asyncio.sleep(1)

async def main():
    start_time = time.time()
    await asyncio.gather(slow_task(), slow_task(), slow_task())
    duration = time.time() - start_time
    print(f"Completed in {duration} seconds")

asyncio.run(main())
优化异步代码的最佳实践

减少上下文切换

上下文切换是指在不同任务之间切换时保存和恢复上下文状态的过程,频繁的上下文切换会增加系统开销,影响性能,以下是一些减少上下文切换的方法:

  • 合并小任务:将多个小任务合并为一个较大的任务,减少切换的频率;
  • 批量处理:使用 asyncio.gatherasyncio.wait一次性处理多个任务。
import asyncio

async def task1():
    await asyncio.sleep(1)
    print("Task 1 completed")

async def task2():
    await asyncio.sleep(2)
    print("Task 2 completed")

async def main():
    await asyncio.gather(task1(), task2())

asyncio.run(main())

2.避免阻塞操作

在异步代码中,任何阻塞操作都会导致性能下降。应尽量避免使用阻塞的I/O操作,改用异步I/O操作。

  • 使用异步库——使用支持异步的库,如 aiohttp代替 requestsaiofiles代替 open
import aiohttp
import aiofiles
import asyncio

async def fetch_url(url):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as response:
            return await response.text()

async def read_file(filename):
    async with aiofiles.open(filename, 'r'as f:
        contents = await f.read()
        return contents

async def main():
    url_content = await fetch_url('http://example.com')
    file_content = await read_file('example.txt')
    print(url_content[:100])  # 打印前100个字符
    print(file_content[:100])  # 打印前100个字符

asyncio.run(main())

3.合理的任务调度

任务调度不当会导致资源浪费和任务延迟。应根据任务的优先级和系统资源情况进行合理的调度。

  • 限制并发任务数量——使用 asyncio.Semaphore限制同时执行的任务数量,防止资源枯竭:
import asyncio
import aiohttp

semaphore = asyncio.Semaphore(5)

async def fetch(url):
    async with semaphore:
        async with aiohttp.ClientSession() as session:
            async with session.get(url) as response:
                return await response.text()

async def main():
    urls = ['http://example.com' for _ in range(100)]
    tasks = [fetch(url) for url in urls]
    results = await asyncio.gather(*tasks)
    print(f"Fetched {len(results)} pages.")

asyncio.run(main())
  • 根据任务优先级进行调度——使用 asyncio.PriorityQueue实现基于优先级的任务调度:
import asyncio
import random

async def worker(name, queue):
    while True:
        priority, task = await queue.get()
        print(f"Worker {name} executing task {task} with priority {priority}")
        await asyncio.sleep(random.random())
        queue.task_done()

async def main():
    queue = asyncio.PriorityQueue()

    for i in range(10):
        priority = random.randint(110)
        queue.put_nowait((priority, f"task {i}"))

    workers = [asyncio.create_task(worker(f"worker-{i}", queue)) for i in range(3)]

    await queue.join()

    for w in workers:
        w.cancel()

asyncio.run(main())
实战示例:高效的异步网络爬虫

为了展示上述优化技巧的应用,下面我们通过一个高效的异步网络爬虫示例来进行演示:

import asyncio
import aiohttp

class AsyncWebCrawler:
    def __init__(self, max_concurrent_requests=5):
        self.semaphore = asyncio.Semaphore(max_concurrent_requests)
        self.session = None

    async def fetch(self, url):
        async with self.semaphore:
            async with self.session.get(url) as response:
                response.raise_for_status()
                return await response.text()

    async def crawl(self, urls):
        async with aiohttp.ClientSession() as session:
            self.session = session
            tasks = [self.fetch(url) for url in urls]
            return await asyncio.gather(*tasks, return_exceptions=True)

    async def main(self, urls):
        results = await self.crawl(urls)
        for url, result in zip(urls, results):
            if isinstance(result, Exception):
                print(f"Error fetching {url}{result}")
            else:
                print(f"Fetched {len(result)} characters from {url}")

if __name__ == "__main__":
    urls = [
        'http://example.com',
        'http://example.org',
        'http://example.net',
        # 添加更多URL
    ]
    crawler = AsyncWebCrawler(max_concurrent_requests=5)
    asyncio.run(crawler.main(urls))
使用 triocurio 提升异步编程体验

除了asyncio,还有其他异步编程库,如triocurio,它们提供了更简单、更直观的异步编程体验:

# 使用trio库
import trio
import asks

async def fetch(url):
    response = await asks.get(url)
    return response.text

async def main():
    urls = ['http://example.com''http://example.org''http://example.net']
    async with trio.open_nursery() as nursery:
        for url in urls:
            nursery.start_soon(fetch, url)

trio.run(main)

结语

​ 异步编程是处理I/O密集型任务的利器,它可以大幅提高程序的响应速度和资源利用率。通过本文的介绍,我们学习了在异步编程中进行性能优化的几种方法,希望这些技巧能帮助你在实际项目中编写出高效、稳定的异步代码!下期将会更系统、更详细的讲解triocurio库,同时将异步与并发结合!如果你对计算机相关技术有更多的兴趣,想要持续的探索,请关注我的公众号哟! alt

本文由 mdnice 多平台发布

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/729500.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

电子设计新宠SmartEDA:揭秘其爆红背后的神秘力量

SmartEDA账号免费领取https://www.ismarteda.com 在当下这个电子科技迅猛发展的时代,电子设计领域的创新层出不穷。其中,SmartEDA作为一颗璀璨的新星,凭借其卓越的性能和便捷的操作体验,迅速在电子设计领域崭露头角,成…

【MAUI】resource xml/file_paths (aka com.xxx.xxx:xml/ file _paths) not found.

APP2260:resource xml/file_paths (aka com.zettlercn.wms:xml/ file _paths) not found. This error is likely caused by an issue with the AndroidManifest.xml file or an Android manifest generation attribute in a source code file MAUI从6.0升级到8.0,调试发现资源…

kylinos 国产操作系统离线安装firefox 麒麟操作系统安装新版本firefox

1. 火狐地址: 下载 Firefox 浏览器,这里有简体中文及其他 90 多种语言版本供您选择 2. 选择: 3. 下载完之后,上传到离线机器 4. 解压缩: tar -xvjf firefox-127.0.1.tar.bz2 5. 去点击解压后的文件夹,找…

mybatisplus字段注入MetaObjectHandler扫描不到我的指定填充字段

使用mybatisplus自带的字段填充策略注入值的时候,发现并没有扫描到我的指定字段。 1. 初始代码 Component Slf4j public class MyMetaObjectHandler implements MetaObjectHandler {private static final String createByFiled "createBy";private stati…

eclipse中没有SERVER的解决办法(超详细)

将 Tomcat 和 Eclipse 相关联时,Eclipse有的版本发现 发现eclipse->【Window】->【Preferences】里没有【server】从而配置不了Runtime Environment。所以需要通过eclipse进行安装。 通过我个人的经验下面给出解决办法: 一、获取 Eclipse版本 点击…

使用MyBatisPlus进行字段的自动填充

使用MyBatisPlus进行字段的自动填充 需求场景 当我们往数据库里面插入一条数据,或者是更新一条数据时,一般都需要标记创建时间create_time和更新时间update_time的值,但是如果我们每张表的每个请求,在执行sql语句的时候我们都手…

绝望的C#:TreeView为什么双击自动展开、折叠?双击事件的参数根本不是双击位置

双击打开编辑窗口应该是个再正常不过的想法吧?但是被自动展开、折叠搅了。 为什么自动展开折叠就出问题了?因为在某些情况下自动展开、折叠改变了节点的显示位置,节点的位置向下了——因为折叠导致下方内容变少,控件为了避免下方出…

六月惊喜| 事件分析Plus上线

前情回顾 ClkLog在四月先上线了一版<事件分析>&#xff0c;可以通过元数据的配置&#xff0c;创建并统计自定义事件的数据情况&#xff08;例如&#xff1a;用户数、触发次数、人均次数&#xff09;。 功能上线后好多小伙伴说希望我们加紧上线自定义的事件分析。ClkLog实…

全新升级微信分销商城小程序源码系统 前后端分离 带完整的安装代码包以及搭建部署教程

系统概述 微信分销商城小程序源码系统是基于先进的技术和理念开发而成的。它旨在为企业和商家打造一个功能齐全、用户体验良好的分销平台&#xff0c;帮助他们更好地管理商品、销售渠道和用户关系&#xff0c;实现业务的快速增长和持续发展。 代码示例 系统特色功能一览 1.多…

JuiceFS 社区版 v1.2 发布,新增企业级权限管理、平滑升级功能

JuiceFS 社区版 v1.2 今天正式发布&#xff0c;这是自 2021 年开源以来的第三个大版本。v1.2 也是一个长期支持版本&#xff08;LTS&#xff09;。我们将持续维护 v1.2 以及 v1.1 这两个版本&#xff0c;v1.0 将停止更新。 JuiceFS 是为云环境设计的分布式文件系统&#xff0c;…

汇川学习笔记7 - 雕刻机项目

1、系统上电轴准备好之后&#xff0c;自动复回原点一次&#xff0c; 2、在雕刻机面板上有三个按钮用来控制画三种图形 3、注意cnc代码放置的文件夹 4、FILE0文件内容 5、FILE1文件内容 6、FILE2文件内容 7、程序代码下载地址 https://download.csdn.net/download/qq_6191667…

HTML(14)——结构伪类选择器和伪元素选择器

结构伪类选择器 作用&#xff1a; 根据元素的结构关系查找元素 选择器说明E:first-child查找第一个E元素E:last-child查找最后一个E元素E:nth-child(N)查找第N个E元素(第一个元素N值为1) 例如&#xff1a;查找第一个li标签&#xff0c;将背景改为绿色 <style> li:fir…

安当透明加密(TDE)助力企业建立可信赖的数据环境

​​​​​​​ 透明加密是一种特殊的加密方法&#xff0c;它允许数据在存储或传输过程中自动进行加密和解密&#xff0c;而用户并不需要知道加密过程。这种技术对用户来说是“透明的”&#xff0c;因为它不会改变用户的日常操作习惯&#xff0c;加密和解密过程在后台自动进行…

leetcode 动态规划(基础版)三角形最小路径和

题目&#xff1a; 题解&#xff1a; 一种可行的方案是从下到上&#xff0c;避免了从上到下的下标特判。走到每一个位置的最小值等于该位置的上两个位置中的最小值加上该位置的值。 int minimumTotal(vector<vector<int>>& triangle) {int dp[205][205]{0};f…

webpack 压缩图片

压缩前&#xff1a; 压缩后&#xff1a; 压缩后基本上是压缩了70-80%左右 1.依赖版本及配置 "imagemin-webpack-plugin": "^2.4.2", "imagemin-mozjpeg": "^7.0.0", "imagemin-pngquant": "^5.0.1", "webpa…

服务器机柜和网络机柜有什么区别

服务器机柜和网络机柜虽然在外观上可能相似&#xff0c;都遵循19英寸的标准&#xff0c;但它们的设计目的、功能、结构和特性存在明显的区别。下面是两者的主要区别&#xff1a; 1. 用途 服务器机柜&#xff1a;主要用于承载和组织服务器设备&#xff0c;包括主机、存储设备、交…

odoo 翻译字段sql查询语句

字段写法&#xff1a; name->>en_US 任务&#xff1a; 查询name字段中&#xff0c;包含ring的数据 SQL模糊查询 SELECT * FROM product_public_category WHERE name->>en_US LIKE %ring%; SQL精准查询 SELECT * FROM product_public_category WHERE name->…

分布式光纤测温DTS在工程现场中稳定性与可靠性如何?

20年前&#xff0c;分布式光纤测温(Distributed Temperature Sensing&#xff0c;DTS)技术的发展尚不成熟&#xff0c;设备成本高昂&#xff0c;其稳定性与可靠性也存在一定问题。然而&#xff0c;经过二十多年的不断发展与创新&#xff0c;DTS技术在工程现场应用中取得了显著进…

算力之困,大模型何解?

互联网企业选择大模型合作伙伴之时&#xff0c;首要考虑的因素是算力。 大模型本身就是巨量参数“力大砖飞”的结晶&#xff0c;也就是说大模型与大算力密不可分。 发展到今天&#xff0c;国内的大模型在对话层面&#xff0c;已经与GPT-3.5接近&#xff0c;但在复杂指令层面与…

QT绘画仪表盘

代码一步一步讲&#xff0c;就不写用啥之类的了&#xff0c;暗部走来&#xff0c;自己找使用的类以及使用方法 1、创建工程 2、重载paintEvent #include <QMainWindow> #include <QPainter> #include <QPaintEvent> protected:virtual void paintEvent(QP…