文章目录

    • 1. 写在最前面
    • 2. Python 语法
      • 2.1 yield
        • 2.1.1 yield 和 return 的区别
        • 2.1.2 golang 中实现 yield 语法
    • 3. aiohttp 库
      • 3.1 原始写法
      • 3.2 修改写法
      • 3.2 耗时对比分析
    • 4. 碎碎念
    • 5. 参考资料

1. 写在最前面

最近加了很多 Python Coding 的任务,虽然在 AI 加持下能够顺利完成,但是还是觉得心理不踏实,觉得很多代码 AI 写完自己不是很懂,不喜欢这种感觉。

刚好周日上午没事,抽空记录在 Python 开发中遇到的神奇语法和库。

2. Python 语法

2.1 yield

修改的代码中,函数的返回很多处用了 Yield 而不是 return ,这引起了我的好奇。

2.1.1 yield 和 return 的区别

在 Python 中,yieldreturn 都用于从函数中返回值,但它们之间有一些重要的区别:

  • 返回类型

    • return:

      • return 语句用于结束函数的执行,并将一个值返回给调用者。函数在执行到 return 时会立即退出。

      • 每次调用函数时,都是从头开始执行,直到遇到 return

    • yield:

      • yield 语句用于定义生成器函数。生成器函数在执行时不会立即返回值,而是返回一个生成器对象。

      • 当生成器函数被调用时,它不会立即执行,而是返回一个生成器对象。可以通过迭代这个生成器对象来逐步执行函数的代码,每次遇到 yield 时返回一个值,并在下一次迭代时从上次停止的地方继续执行。

  • 内存使用

    • return:

      • 返回一个完整的结果(例如一个列表),可能会占用较多内存,特别是当结果很大时。
    • yield:

      • 生成器按需生成值,通常会更节省内存,特别是在处理大型数据集时,因为它不会一次性生成所有结果。
  • yield 的使用场景:

    • 内存效率:适合处理大数据集,避免一次性加载。

    • 无限序列:可生成无限序列,按需计算。

    • 状态保持:在函数中保持状态,适合需要维护状态的场景。

    • 协程:在异步编程中用于协作式多任务。

    • 管道处理:构建数据处理管道,方便数据流动。

  • 示例

    • 使用 return 的函数:

      def get_squares(n):return [x*x for x in range(n)]squares = get_squares(5)
      print(squares)  # 输出: [0, 1, 4, 9, 16]
      
    • 使用 yield 的生成器:

      def get_squares(n):for x in range(n):yield x*xsquares_gen = get_squares(5)
      for square in squares_gen:print(square)  # 输出: 0, 1, 4, 9, 16
      
2.1.2 golang 中实现 yield 语法

之前写的是 golang ,为了用类比法更好的理解 yield ,可以在 golang 中实现一个类似能力的示例。

package mainimport ("fmt"
)// 生成器函数,返回一个通道
func getSquares(n int) <-chan int {ch := make(chan int) // 创建一个通道go func() {for x := 0; x < n; x++ {ch <- x * x // 将计算结果发送到通道}close(ch) // 关闭通道,表示没有更多值}()return ch // 返回通道
}func main() {squares := getSquares(5) // 获取生成器通道for square := range squares { // 迭代通道中的值fmt.Println(square) // 输出: 0, 1, 4, 9, 16}
}

函数说明:

  • 通道:在 getSquares 函数中,我们创建了一个通道 ch,用于发送计算结果。

  • goroutine:我们使用 go 关键字启动了一个 goroutine,在这个 goroutine 中计算平方并将结果发送到通道。

  • 关闭通道:当所有值都发送完后,我们关闭通道,以便接收方知道没有更多值可供接收。

  • 迭代通道:在 main 函数中,我们使用 range 迭代通道,从中接收值。

3. aiohttp 库

需求是需要在客户请求大模型前,提前发送一次请求大模型,确保在客户请求的时候,就可以节省掉 tls 握手和 tcp 建立连接的时间,简称之为预热。

3.1 原始写法

async def analyze_backend_consistency(num_requests: int = 5, delay: float = 0.5, concurrent: bool = False):# 顺序发送请求results = []for i in range(num_requests):try:connector = aiohttp.TCPConnector(ssl=True)async with aiohttp.ClientSession(connector=connector) as session:result = await make_request(session, i + 1)results.append(result)if i < num_requests - 1:await asyncio.sleep(delay)except Exception as e:print(f"请求 {i + 1} 失败: {str(e)}")# 打印每个请求的结果for result in results:print(f"\n请求 {result['request_id']} 结果:")print(f"远程IP:端口 = {result['remote_ip']}:{result['remote_port']}")print(f"请求ID = {result['x_request_id']}")print(f"处理时间 = {result['upstream_time']}ms")print(f"总响应时间 = {result['response_time']}ms")print("-" * 50)# 分析结果print("\n分析结果:")unique_ips = set(r['remote_ip'] for r in results)print(f"使用的不同IP数量: {len(unique_ips)}")print(f"IP列表: {', '.join(str(ip) for ip in unique_ips)}")# 计算平均响应时间avg_response_time = sum(float(r['response_time']) for r in results) / len(results)print(f"平均响应时间: {avg_response_time:.2f}ms")# 检查是否所有请求都使用了同一个连接print(f"所有请求是否使用同一个连接: {len(unique_ips) == 1}")# 分析处理时间upstream_times = [float(r['upstream_time']) for r in results]print(f"后端处理时间范围: {min(upstream_times):.2f}ms - {max(upstream_times):.2f}ms")print(f"后端处理时间平均值: {sum(upstream_times)/len(upstream_times):.2f}ms")

测试结果:

在这里插入图片描述

3.2 修改写法

async def analyze_backend_consistency(num_requests: int = 5, delay: float = 0.5, concurrent: bool = False):connector = aiohttp.TCPConnector(ssl=True)async with aiohttp.ClientSession(connector=connector) as session:results = []if concurrent:# 并发发送所有请求tasks = [make_request(session, i + 1) for i in range(num_requests)]results = await asyncio.gather(*tasks)else:# 顺序发送请求for i in range(num_requests):try:result = await make_request(session, i + 1)results.append(result)if i < num_requests - 1:await asyncio.sleep(delay)except Exception as e:print(f"请求 {i + 1} 失败: {str(e)}")# 打印每个请求的结果for result in results:print(f"\n请求 {result['request_id']} 结果:")print(f"远程IP:端口 = {result['remote_ip']}:{result['remote_port']}")print(f"请求ID = {result['x_request_id']}")print(f"处理时间 = {result['upstream_time']}ms")print(f"总响应时间 = {result['response_time']}ms")print("-" * 50)# 分析结果print("\n分析结果:")unique_ips = set(r['remote_ip'] for r in results)print(f"使用的不同IP数量: {len(unique_ips)}")print(f"IP列表: {', '.join(str(ip) for ip in unique_ips)}")# 计算平均响应时间avg_response_time = sum(float(r['response_time']) for r in results) / len(results)print(f"平均响应时间: {avg_response_time:.2f}ms")# 检查是否所有请求都使用了同一个连接print(f"所有请求是否使用同一个连接: {len(unique_ips) == 1}")# 分析处理时间upstream_times = [float(r['upstream_time']) for r in results]print(f"后端处理时间范围: {min(upstream_times):.2f}ms - {max(upstream_times):.2f}ms")print(f"后端处理时间平均值: {sum(upstream_times)/len(upstream_times):.2f}ms")

测试结果:
在这里插入图片描述

3.2 耗时对比分析

原始写法修改写法
特点每个请求都创建新的 TCPConnector 和 ClientSession
每次请求都要重新建立 TCP 连接和 TLS 握手
不复用 HTTP/2 连接
每个请求的耗时 = TCP建立(~40ms) + TLS握手(~200ms) + 请求处理时间
只创建一次 TCPConnector 和 ClientSession
TCP 连接和 TLS 握手只进行一次
复用 HTTP/2 连接
第一个请求耗时 = TCP建立 + TLS握手 + 请求处理时间
后续请求耗时 = 请求处理时间

4. 碎碎念

周日的时候写了 80%,今晚刚好手里的活搞的差不多了,给总结收个尾。上海最近的暴雨和雷声有点子吓人:

  • 世间最重要的事莫过于懂得让自己属于自己。

  • 偶尔觉得妈妈很丢人,妈妈为什么连起码的脸面的自尊都没有呢?我都觉得上火。比起她自己,她有更想守护的,那就是我。人真正变强大,不是因为守护着自尊心,而是抛开自尊心的时候。所以妈妈很强大。

这周就要回去看妈妈啦,开心,就写到这里吧。

5. 参考资料

  • 如何理解Python中的yield用法?
  • https://docs.aiohttp.org/en/stable/tracing_reference.html#aiohttp-client-tracing-reference

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Ollama:本地大语言模型部署和使用详解

1.什么是Ollama&#xff1f; Ollama是一个开源的大语言模型管理工具&#xff0c;具有以下特点&#xff1a; 简单易用&#xff1a;提供简单的命令行接口本地部署&#xff1a;模型运行在本地&#xff0c;保护数据隐私跨平台支持&#xff1a;支持Windows、macOS、Linux丰富的模型…

云计算学习100天-第41天 -普罗米修斯2

目录 五、添加被监控端 1、在web1[192.168.88.100]上部署node exporter 2、在Prometheus服务器上添加监控节点 3、浏览器查看添加结果 六、Grafana的部署 概述 部署步骤 七、监控MySQL数据库 1、配置MySQL 2、配置mysql exporter 3、配置prometheus监控mysql 五、添…

集成电路学习:什么是SVM支持向量机

SVM:支持向量机 SVM,即支持向量机(Support Vector Machine),是一种常用的机器学习算法,特别适用于分类和回归问题。以下是对SVM的详细解析: 一、SVM的基本原理 SVM的基本思想是在特征空间中寻找一个最优的超平面,使得不同类别的样本能够被最大化地分开。这个最优…

盲盒抽谷机小程序开发:如何用3D技术重构沉浸式体验?

在盲盒经济中&#xff0c;“沉浸感”是提升用户停留时长与转化率的核心武器。某品牌通过3D扭蛋机旋转、卡牌翻转特效&#xff0c;使用户停留时长从15秒延长至45秒&#xff0c;转化率提升25%&#xff1b;另一品牌上线AR试戴功能后&#xff0c;单次抽谷时长延长至2分钟&#xff0…

集采与反腐双重压力下,医药销售的破局之道:从资源依赖到价值重构

在医药行业进入集采常态化与反腐纵深推进的新阶段&#xff0c;“资源匮乏”“拜访受阻” 成为萦绕在众多医药销售人员心头的难题。当传统的资金投入、学术活动等资源型打法逐渐失效&#xff0c;行业正面临一场从 “资源驱动” 到 “价值驱动” 的深刻变革。那些曾在市场中创造过…

Elasticsearch常用命令(未完)

网上针对es常用命令好多都是写的感觉非常复杂难以理解&#xff0c;所以我还是自己整理了一下相关的常用命令。 对es输入指令可以用很多种方法比如用es的谷歌浏览器插件&#xff0c;亦或者postman&#xff0c;我个人比较喜欢用postman比较简单直接 1.删除指定索引下的所有数据…

【系统架构设计(七)】 需求工程之:面向对象需求分析方法:统一建模语言(UML)(下)

文章目录一、用例图1. 用例模型建立的系统化流程第一步&#xff1a;识别参与者第二步&#xff1a;合并需求获得用例第三步&#xff1a;细化用例描述第四步&#xff1a;调整用例模型&#xff08;可选步骤&#xff09;2. 用例之间的关系类型二、类图与对象图概念类之间的关系三、…

数据结构——树(04二叉树,二叉搜索树专项,代码练习)

文章目录一、概念二、构造1.1先序序列 构造BST1.2中序序列 转换为BST1.3中序序列链表转换为BST1.4BST转换为中序序列链表1.7BST的序列化和反序列化1.6BST的种数二、BST的增删改查2.1验证是否为BST2.2查找值为val的节点2.3插入一个值为val的节点2.4删除一个值为val的节点2.5恢复…

ArkUI核心功能组件使用

1.Tabs&#xff08;选项卡&#xff09; 1.1 概述 Tabs组件的页面组成包含两个部分&#xff0c;分别是TabContent和TabBar。TabContent是内容页&#xff0c;TabBar是导航页签栏。 TabBar是导航页签栏&#xff0c;页面结构如下图所示&#xff0c;根据不同的导航类型&#xff0c;布…

Qt5 多媒体大纲

一、入门准备 基础知识 熟悉 Qt 的信号槽机制、事件循环 掌握 .pro 工程文件配置&#xff08;QT multimedia multimediawidgets&#xff09; 熟悉常见的音视频格式与编解码器基础 环境配置 Qt Creator Qt 5.x 确认安装了 multimedia 模块与 mediaservice 插件 熟悉调试…

音频数据集采样率选择建议

你好&#xff01;这是一个非常棒且非常重要的问题&#xff0c;在音频机器学习项目中&#xff0c;选择合适的采样率是平衡计算效率和模型性能的关键。 直接回答你的问题&#xff1a;将音频下采样到 800 Hz 对于绝大多数音频分类任务来说都太低了&#xff0c;几乎肯定会丢失大量关…

深度学习系列 | Seq2Seq端到端翻译模型

一、通俗总结Seq2Seq 就像一个 “序列转换器”&#xff1a;先把输入的一段话 “压缩成一个核心意思”&#xff0c;再根据这个意思 “一句句生成另一段话”&#xff0c;能搞定翻译、听写这类 “输入输出不一样长” 的任务&#xff0c;但太长的内容可能记不全&#xff0c;还容易越…

Spring MVC BOOT 中体现的设计模式

Spring:创建型:单例模式:Bean默认就是单例的&#xff0c;是饿汉模式的&#xff0c;但是可以通过Lazy设置为懒汉工厂模式&#xff1a;可自定义FactroyBean&#xff0c;实现Bean自己的生产工厂结构型:代理模式&#xff1a;AOP就是典型的动态代理&#xff0c;有jdk和cglib两种实现…

Chrome浏览器调用ActiveX控件之allWebOffice在线编辑控件

背景 allWebOffice控件能够实现在浏览器窗口中在线操作文档的应用&#xff08;阅读、编辑、保存等&#xff09;&#xff0c;支持编辑文档时保留修改痕迹&#xff0c;支持书签位置内容动态填充&#xff0c;支持公文套红&#xff0c;支持文档保护控制等诸多办公功能&#xff0c;本…

嵌入式 - 硬件:51单片机

本节重点1. MCU、CPU、GPU、NPU、SOC、MPU、FPU2. 内存、外存的区别3. RAM和ROM的区别&#xff0c;单片机RAM大小4. 三大总线及其特点5. 发光二极管分类及其特点6. 数码管显示原理一、嵌入式以应用为中心&#xff0c;以计算机技术为基础&#xff0c;软硬件可裁剪的专用计算机系…

Java Spring Boot 中 Redis 缓存穿透问题排查与解决方案

前言 作为一名普通的 Java 程序开发者&#xff0c;日常开发中难免会遇到一些看似简单但实际排查起来非常棘手的问题。在最近的一个项目中&#xff0c;我遇到了一个 Redis 缓存穿透的问题&#xff0c;导致系统在高并发下性能急剧下降&#xff0c;甚至出现服务响应超时的情况。这…

Ubuntu下配置并远程连接MySQL

1、安装mysql-serverapt update apt install mysql-server2、修改配置文件/etc/mysql/mysql.conf.d/mysqld.cnfbind-address 0.0.0.0 mysqlx-bind-address 0.0.0.03、启动并设置服务为开机自启动systemctl enable mysql.service --now4、查看服务状态systemct…

开源 C++ QT Widget 开发(九)图表--仪表盘

文章的目的为了记录使用C 进行QT Widget 开发学习的经历。临时学习&#xff0c;完成app的开发。开发流程和要点有些记忆模糊&#xff0c;赶紧记录&#xff0c;防止忘记。 相关链接&#xff1a; 开源 C QT Widget 开发&#xff08;一&#xff09;工程文件结构-CSDN博客 开源…

怎么为服务器设置或重置服务器密码?

创建服务器后&#xff0c;您可以设置服务器的登录密码&#xff0c;如果你忘记了密码&#xff0c;可以重新设置实例的密码。本文讲一下如何重置阿里云服务器密码。使用限制&#xff1a;离线重置密码仅支持在控制台设置或重置服务器管理员账号的密码。•Windows 实例的默认用户名…

【线性代数入门 | 那忘算8】洛谷P3389 高斯消元(内附行列式教学)

想了想还是单开了一篇&#xff0c;数学王子值得&#xff01; 专栏指路&#xff1a;《再来一遍一定记住的算法&#xff08;那些你可能忘记了的算法&#xff09;》 前置知识&#xff1a; 矩阵&#xff1a;数的集合&#xff0c;一般是方程的系数。 题面&#xff1a; 洛谷P3389 …