[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 result


def thread_func(df_code, tnum, list_num):
    bi = tnum*list_num
    ei = bi+list_num
    if 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 result

def thread_func(df_code, tnum, list_num):
    rss = requests.session()
    bi = tnum*list_num
    ei = bi+list_num
    if 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的性能

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

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

相关文章

ArmV8常用汇编指令2

接上文&#xff0c;我们来分析一些具体指令。 1.加载存储指令 Load/Store可以分为立即数、寄存器等操作&#xff0c;格式如下&#xff1a; 这里Rn和Rt均为4位&#xff0c;原因在于&#xff0c;A32/T32是16个通用寄存器。因此使用4bit刚好可以遍历所有。如果是运行在AArch64&a…

Spring Task使用介绍

文章目录 Spring Task介绍cron表达式入门案例Spring Task使用步骤全注解的方式代码开发测试结果 代码仓库 Spring Task 介绍 Spring Task 是Spring框架提供的任务调度工具&#xff0c;可以按照约定的时间自动执行某个代码逻辑。 定位定时任务框架 作用定时自动执行某段Java…

python爬虫概述及简单实践:获取豆瓣电影排行榜

目录 前言 Python爬虫概述 简单实践 - 获取豆瓣电影排行榜 1. 分析目标网页 2. 获取页面内容 3. 解析页面 4. 数据存储 5. 使用代理IP 总结 前言 Python爬虫是指通过程序自动化地对互联网上的信息进行抓取和分析的一种技术。Python作为一门易于学习且强大的编程语言&…

Ps:锁定图层

使用“图层”面板上的锁定图层 Lock Layer功能可以完全或部分锁定图层以保护其内容。 比如&#xff0c;在完成某个图层后希望它不再被修改&#xff08;包括不透明度和图层样式等&#xff09;&#xff0c;可将其完全锁定。 如果不想更改图像&#xff0c;但对其摆放位置还在犹豫不…

SpringBoot实现IP地址归属地查询

SpringBoot实现IP地址归属地查询 功能特性 标准化的数据格式 每个 IP 数据段的 region 信息都固定了格式&#xff1a; 国家|区域|省份|城市|ISP&#xff0c;只有中国的数据绝大部分精确到了城市&#xff0c;其他国家部分数据只能定位到国家&#xff0c;后前的选项全部是 0。…

6.运行mysql容器-理解容器数据卷

运行mysql容器-理解容器数据卷 1.什么是容器数据卷2.如何使用容器数据卷2.1 数据卷挂载命令2.2 容器数据卷的继承2.3 数据卷的读写权限2.4 容器数据卷的小实验&#xff08;加深理解&#xff09;2.4.1 启动挂载数据卷的centos容器2.4.2 启动后&#xff0c;在宿主机的data目录下会…

demo(三)eurekaribbonhystrix----服务降级熔断

一、介绍&#xff1a; 1、雪崩&#xff1a; 多个微服务之间调用的时候&#xff0c;假如微服务A调用微服务B和微服务C&#xff0c;微服务B和微服务C又调用其他的微服务&#xff0c;这就是所谓的"扇出"。如果扇出的链路上某个微服务的调用响应的时间过长或者不可用&am…

【flutter】使用getx下的GetMaterialApp创建路由和使用时间选择器国际化问题

GetMaterialApp是啥 网上解释说是 MaterialApp Getx properties GetMaterialApp 问题 在使用showDateRangePicker组件的时候&#xff0c; 一直报错 No MaterialLocalizations found 我就愁思是不是GetMaterialApp跟MaterialApp方法不一样的问题&#xff0c;结果不是&#…

【7】Spring Boot 3 集成组件:缓存组件 spring cache + spring data redis

目录 【7】Spring Boot 3 集成组件&#xff1a;缓存组件 spring cache spring data redis什么是缓存抽象声明式注解JSR-107对应SpEL上下文数据 引入依赖cache 支持的缓存类型缓存类型配置NONESIMPLEREDIS自定义配置 CAFFEINE Hazelcast...总结 个人主页: 【⭐️个人主页】 需要…

【第2章 Node.js基础】2.7 Node.js 的流(一) 可读流

&#x1f308; Node.js 的流 &#x1f680;什么是流 流不是 Node.js 特有的概念。它们是几十年前在 Unix 操作系统中引入的。 我们可以把流看作这些数据的集合&#xff0c;就像液体一样&#xff0c;我们先把这些液体保存在一个容器里&#xff08;流的内部缓冲区 BufferList&…

Windows SmartScreen中的漏洞!

&#x1f525;另一个流行漏洞是 CVE-2023-36025 - 绕过 Windows SmartScreen 安全功能&#xff0c;该功能是多个微软产品的网络钓鱼和恶意软件保护组件。 &#x1f47e;有多危险 利用该漏洞&#xff0c;攻击者可以绕过 Windows Defender SmartScreen 检查和相关警告。利用该漏…

【Python】Pandas(学习笔记)

一、Pandas概述 1、Pandas介绍 2008年WesMcKinney开发出的库&#xff0c;专门用于数据挖掘的开源python库 以Numpy为基础&#xff0c;借力Numpy模块在计算方面性能高的优势 基于matplotib&#xff0c;能够简便的画图 独特的数据结构 import pandas as pd2、Pandas优势 便…

Dart 3.2 更新,Flutter Web 的未来越来越明朗

参考原文&#xff1a;https://medium.com/dartlang/dart-3-2-c8de8fe1b91f 本次跟随 Flutter 3.16 发布 的 Dart 3.2 &#xff0c;包含有&#xff1a;私有 final 字段的非空改进、新的 interop 改进、对 DevTools 中的扩展支持、以及对 Web 路线图的更新&#xff0c;包括对 Was…

Unity开发之C#基础-集合(字典)(Dictionary)

前言 Hello 兄弟们 一转眼俩月又过去了&#xff08;失踪人口回归&#xff09; 不出意外的是出意外了 失踪了两个月 有点对不起我这为数不多的粉丝们 实不相瞒忙的焦头烂额 也没心情写博客 实在对不住各位 好了长话短说 今天这篇文章是讲解c#当中的新的一种集合的表现&#xff…

ProtocolBuffers(protobuf)详解

目录 前言特点语法定义关键字JSON与Protocol Buffers互相转换gRPC与Protocol Buffers的关系 前言 Protocol Buffers&#xff08;通常简称为protobuf&#xff09;是Google公司开发的一种数据描述语言&#xff0c;它能够将结构化数据序列化&#xff0c;可用于数据存储、通信协议…

pip 问题

升级pip命令&#xff1a; python -m pip install --upgrade pippip不能下载pytorch&#xff1a; 这个问题我一直没解决。不知道有哪位大佬可以留言给我。把whl文件下载到本地也没有&#xff0c;pip不会进行本地文件夹搜索。

园区网络项目实战

实验背景 某写字楼备搭建一张网络供楼内企业办公使用。写字楼共6层&#xff0c;目前已有三层投入使用&#xff0c;分别 是一层会客大厅、二层行政部及总经理办公室、三层研发部和市场部。一层设有核心机房&#xff0c;其 他各楼层均有一个小房间放置网络设备。 第一步 询…

程序员如何悄悄拔尖,然后惊艳四座?

谁最初还不是个血气方刚、胸怀抱负的有志青年了&#xff1f; 渐渐的&#xff0c;被岁月磨平棱角&#xff0c;被生活冲淡理想&#xff0c;如今的你还有几分似从前&#xff1f; 你是否&#xff0c;不安现状、焦虑未来、忙忙碌碌没有方向&#xff1f; 不甘平庸?不想摸鱼&#…

【LeetCode刷题-滑动窗口】--1004.最大连续1的个数III

1004.最大连续1的个数III 方法&#xff1a;滑动窗口 class Solution {public int longestOnes(int[] nums, int k) {int left 0,right 0,zero 0,res 0;while(right < nums.length){if(nums[right]0){zero;}while(zero > k){if(nums[left] 0){zero--;}left;}res Ma…

深度系统(Deepin)开机无法登录,提示等待一千五百分钟

深度系统&#xff08;Deepin&#xff09;20.0&#xff0c; 某次开机无法登录&#xff0c;提示等待一千五百分钟。 &#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff1f; 用电脑这么多年&#xff0c;头一回遇到这种…
最新文章