当前位置: 首页 > news >正文

[Python学习笔记]Requests性能优化之Session

Requests 可是说是 Python 中最常用的库了。用法也非常简单,但是想真正的用的好并不容易。

下面介绍一个提升性能小技巧:使用 session 会话功能。
以下是 Requests 官网的介绍:

  • 会话对象让你能够跨请求保持某些参数。它也会在同一个 Session 实例发出的所有请求之间保持 cookie, 期间使用 urllib3 的 connection pooling 功能。所以如果你向同一主机发送多个请求,底层的 TCP 连接将会被重用,从而带来显著的性能提升。

目录

    • 0. 优化效果
    • 1. 优化过程
      • 1.1. 优化前
      • 1.2. 优化后
    • 2. 网络连接数对比
      • 2.1. 优化前
      • 2.2. 优化后
    • 3. session 进阶设置
    • 参考

以下示例脚本采用的是在之前的章节[量化投资-学习笔记013]Python+TDengine从零开始搭建量化分析平台-策略回测进阶中的回测脚本。
程序会查询 9037 张股票的近10个月的交易数据,使用交易策略进行回测,并将回测结构写入数据库。

涉及数据量:
查询 9037 张表,共 1779929 条数据;写入 9037 张表,每个表 1 条数据。

0. 优化效果

优化前后对比程序执行耗时
优化前1m44.5s
优化后30.57s

1. 优化过程

当时为提示写入效率,采用多进程/线程的方式,将回测数据写入数据库。

1.1. 优化前

线程数=1

# time python3 macd_all_code.py
real    1m44.506s
user    0m10.732s
sys     0m1.620s

线程数=2

# time python3 macd_all_code.py 
real    2m45.544s
user    0m20.274s
sys     0m2.338s

时间反而增加了1倍,完全不符合设计逻辑。。

因为数据库部署在本地,磁盘为SSD,CPU负载也不高,因此初步判断问题出在程序内部。
首先排查的就是网络连接部分,因为要查询 9037 张表,每个表发起一次连接(TCP三次握手+四次挥手),这部分确实会耗时较高。
修改代码,使用 session,保证每个线程只建立一次连接。

修改前代码:

def get_request(sql):sql = sql.encode("utf-8")headers = {'Connection': 'keep-alive','Accept-Encoding': 'gzip, deflate, br'}response = requests.post(url, data=sql, auth=(username, password), headers=headers)data = json.loads(response.content.decode())result = data.get("data")return resultdef thread_func(df_code, tnum, list_num):bi = tnum*list_numei = bi+list_numif tnum < (threadNum-1):df = df_code.iloc[bi:ei, :]else:df = df_code.iloc[bi:len(df_code), :]df_profit = loop_bt(df)write_td(df_profit)rss.close()

修改后代码:

def get_request(sql, rss):sql = sql.encode("utf-8")headers = {'Connection': 'keep-alive','Accept-Encoding': 'gzip, deflate, br'}response = rss.post(url, data=sql, auth=(username, password), headers=headers)data = json.loads(response.content.decode())result = data.get("data")return resultdef thread_func(df_code, tnum, list_num):rss = requests.session()bi = tnum*list_numei = bi+list_numif tnum < (threadNum-1):df = df_code.iloc[bi:ei, :]else:df = df_code.iloc[bi:len(df_code), :]df_profit = loop_bt(df, rss)write_td(df_profit, rss)rss.close()
  • 以上只贴了关键两部分代码,其他代码请参考《[量化投资-学习笔记013]Python+TDengine从零开始搭建量化分析平台-策略回测进阶》章节。

1.2. 优化后

threadNum=1

# time python3 macd_all_code_request.py 
real    0m30.566s
user    0m8.497s
sys     0m1.344s

threadNum=2

# time python3 macd_all_code_request.py 
real    0m32.053s
user    0m17.897s
sys     0m1.604s

虽然线程数的提示并没有提示效率,但通过使用 session, 程序整体执行效率提示了 3 倍。

2. 网络连接数对比

以下是测试过程中网络连接数的变化:

2.1. 优化前

未使用session,线程数=1

# ss -s
Total: 181
TCP:   4254 (estab 1, closed 4252, orphaned 0, timewait 4252)Transport Total     IP        IPv6
RAW       0         0         0
UDP       9         5         4
TCP       2         2         0
INET      11        7         4
FRAG      0         0         0

未使用session,线程数=2

# ss -s
Total: 182
TCP:   4203 (estab 0, closed 4200, orphaned 0, timewait 4200)Transport Total     IP        IPv6
RAW       0         0         0
UDP       9         5         4
TCP       3         3         0
INET      12        8         4
FRAG      0         0         0

2.2. 优化后

使用session,线程数=1

# ss -s
Total: 183
TCP:   3 (estab 1, closed 1, orphaned 0, timewait 1)Transport Total     IP        IPv6
RAW       0         0         0
UDP       10        6         4
TCP       2         2         0
INET      12        8         4
FRAG      0         0         0

使用session,线程数=2

# ss -s
Total: 182
TCP:   4 (estab 2, closed 1, orphaned 0, timewait 1)Transport Total     IP        IPv6
RAW       0         0         0
UDP       9         5         4
TCP       3         3         0
INET      12        8         4
FRAG      0         0         0

通过以上对比发现,网络连接数大幅下降,从优化前的 4000 多个 下降到 2-4 个。

3. session 进阶设置

class requests.adapters.HTTPAdapter(pool_connections=10, pool_maxsize=10, max_retries=0, pool_block=False)[source]
The built-in HTTP Adapter for urllib3.Provides a general-case interface for Requests sessions to contact HTTP and HTTPS urls by implementing the Transport Adapter interface. This class will usually be created by the Session class under the covers.Parameters
- pool_connections – The number of urllib3 connection pools to cache.
- pool_maxsize – The maximum number of connections to save in the pool.
- max_retries – The maximum number of retries each connection should attempt. Note, this applies only to failed DNS lookups, socket connections and connection timeouts, never to requests where data has made it to the server. By default, Requests does not retry failed connections. If you need granular control over the conditions under which we retry a request, import urllib3’s Retry class and pass that instead.
- pool_block – Whether the connection pool should block for connections.

我在代码中添加了相关设置

rss.mount('http://', requests.adapters.HTTPAdapter(pool_connections=20, pool_maxsize=20, max_retries=3))

但是执行速度并没有提升,看来瓶颈已经不在网络连接方面了。

后面持续进行优化吧。

参考

官方文档-高级用法-会话对象
python3 requests使用连接池
[Python] 用Session()优化requests的性能

相关文章:

  • spark性能调优 | 内存优化
  • 科学上网导致Adobe软件运行弹出This non-genuine Adobe app will be disabled soon,尝试解决办法
  • bug:Junit5报错,@SpringBootTest没有运行
  • C#语言的由来与发展历程
  • uart控制led与beep
  • QT绘图设备
  • 大数据-之LibrA数据库系统告警处理(ALM-12051 磁盘Inode使用率超过阈值)
  • torch - 张量Tensor常见的形式
  • Docker Golang 开发环境搭建指南
  • 【MATLAB源码-第77期】基于matlab的OCDM系统在AWGN信道下理论误码率和实际误码率对比仿真。
  • IP池大小重要吗?
  • 华为与美团达成合作,正式启动鸿蒙原生应用开发。
  • 麦克纳姆轮x运动学分析
  • 滑动窗口题目总结(持续更新中)
  • 变长子网划分问题的二叉树解法
  • JS中 map, filter, some, every, forEach, for in, for of 用法总结
  • [译]CSS 居中(Center)方法大合集
  • 【知识碎片】第三方登录弹窗效果
  • Bytom交易说明(账户管理模式)
  • Javascript编码规范
  • JavaScript异步流程控制的前世今生
  • Node.js 新计划:使用 V8 snapshot 将启动速度提升 8 倍
  • Python利用正则抓取网页内容保存到本地
  • React-Native - 收藏集 - 掘金
  • 简单实现一个textarea自适应高度
  • 聚类分析——Kmeans
  • 日剧·日综资源集合(建议收藏)
  • 数据库写操作弃用“SELECT ... FOR UPDATE”解决方案
  • 突破自己的技术思维
  • 项目实战-Api的解决方案
  • 再谈express与koa的对比
  • Java性能优化之JVM GC(垃圾回收机制)
  • ​【已解决】npm install​卡主不动的情况
  • ​VRRP 虚拟路由冗余协议(华为)
  • ​中南建设2022年半年报“韧”字当头,经营性现金流持续为正​
  • #我与Java虚拟机的故事#连载01:人在JVM,身不由己
  • (¥1011)-(一千零一拾一元整)输出
  • (力扣记录)235. 二叉搜索树的最近公共祖先
  • (亲测)设​置​m​y​e​c​l​i​p​s​e​打​开​默​认​工​作​空​间...
  • (四)TensorRT | 基于 GPU 端的 Python 推理
  • (原创)boost.property_tree解析xml的帮助类以及中文解析问题的解决
  • (转)清华学霸演讲稿:永远不要说你已经尽力了
  • .aanva
  • .net mvc actionresult 返回字符串_.NET架构师知识普及
  • .NET(C#、VB)APP开发——Smobiler平台控件介绍:Bluetooth组件
  • .netcore 如何获取系统中所有session_ASP.NET Core如何解决分布式Session一致性问题
  • .net下简单快捷的数值高低位切换
  • /dev/sda2 is mounted; will not make a filesystem here!
  • /dev/VolGroup00/LogVol00:unexpected inconsistency;run fsck manually
  • @Async注解的坑,小心
  • @Autowired标签与 @Resource标签 的区别
  • @ModelAttribute使用详解
  • @四年级家长,这条香港优才计划+华侨生联考捷径,一定要看!
  • [ MSF使用实例 ] 利用永恒之蓝(MS17-010)漏洞导致windows靶机蓝屏并获取靶机权限
  • [bzoj 3124][sdoi 2013 省选] 直径