Python 踩坑记 -- 调优

前言

继续解决问题

一个服务运行有点慢,当然 Python 本身不快,如果再编码不当那这个可能就是量级上的劣化。
整个 Code 主线逻辑 1700+,各依赖封装 3000+,主线逻辑也是很久远的痕迹,长函数都很难看清楚一个 if else 的分支块到哪。
主线逻辑理清楚后,剔除其中诸多已失去意义的逻辑和无效操作,但是整体功能运行时常并未缩短,深入看下具体卡点原因。
调优肯定离不开 Profile 工具,参考下官方介绍:Python 性能分析器
简单来说,就是可以,如下命令生成我们的 profile 分析文件

python -m cProfile -o my_script.prof my_script.py

再借助 flameprof 将 分析文件转为火焰图

# 安装
pip install flameprof
# 将上文的 分析文件 my_script.prof 转图片
python flameprof my_script.prof > my_script.svg

性能开销
上图可以看出,主要的性能开销是在 字符串的 splitlines 和 正则的 search 上,层层找下去,定位到 Code 逻辑:

rules = [rule1, rule2, rule3, ...., rule50]
source_text = [text1, text2, text3, ...., text400]

def parse_data(text_str):
	result = {}
	for rule in rules:
		do_one_rule(rule, text_str, result)
	
	search_objects = re.search(r'some_pattern', text_str)
	if search_objects:
		objects = search_objects.group.split('; ')
		for obj in objects:
			# do something
			pass
	

def do_one_rule(rule, test_str, result):
	for line in test_str.splitlines():
		data = rule(line)
		result.update(data)

剔除多余分支,保留核心卡点逻辑,基本能识别出火焰图中卡点的根因了,这段 code 的目的是对文本中的内容做清理,得出想要的数据

  • 在每个 rule 的解析过程中,重复对原始的 test_str 做了 splitlines 的操作,直接就是性能途中一个主要卡点处
  • 正则中的匹配,首先有个不好习惯,没有去 compile pattern,并且 pattern 也是固定的,每次 search 的时都会重复执行 compile
  • 其次,这里的 search 实际功能就是匹配到其中某一行,而后再对该行处理,并且该行有一定特性,完全可以用字符串前缀匹配 和 关键字匹配来达到同样效果
  • 原始的文本 text_str 是由一些很大段的行可以先行剔除,来加速此处的匹配

优化后效果:
在这里插入图片描述
可以看出,主要开销点都没有,直观测试效果是 原始的功能块从 耗时 15s + -> 3s -
找出点了,仿佛也很简单,但是在长久迭代中,随着原始文本的增长,rule 的增多性能会有明显劣化。

内存泄漏

承接前文的的内存泄漏,修复了全局变量后,仍然会出现,内存的 profile 工具推荐 memray https://bloomberg.github.io/memray/getting_started.html,参考文档使用并不复杂。
通过图形基本确定了开销点

程序中会从 DB 读取全表数据,40w+ 行,整体会持续不断去 append 数组,这种不停数组扩容的情形,导致了有部分容量的内存够分配后不回收

Flask 上下文不一致

Flask 框架搭建服务,单个 app,使用了 werkzeug 的工功能来做 request 级别隔离的上下文管理,结果发现内容会串,无法做到 request 级别正确隔离,原始 code 如下

from flask import Flask
from werkzeug.local import Local, LocalManager

local_store = Local()
local_manager = LocalManager([local_store])


app = Flask(__name__)
app.wsgi_app = local_manager.make_middleware(app.wsgi_app)

Flask 本身推荐了 g 用来做 request 级别的上下文存储,关于 Flask 的上下文 LocalLocalStackLocalProxy 是茫茫多的信息量,得空再细说吧。

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

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

相关文章

【因果推断python】32_合成控制2

目录 合成控制作为线性回归的一种实现​编辑 合成控制作为线性回归的一种实现 为了估计综合控制的治疗效果,我们将尝试构建一个类似于干预期之前的治疗单元的“假单元”。然后,我们将看到这个“假单位”在干预后的表现。合成控制和它所模仿的单位之间的…

16个不为人知的资源网站,强烈建议收藏!

整理了16个不为人知的资源网站,涵盖了课程学习、办公技能、娱乐休闲、小说音乐等多种资源,强烈建议收藏! #学习网站 1、中国大学MOOC icourse163.org/ 这是一个汇集了国内顶尖大学免费课程资源的平台,众多985工程院校如北京大…

C#聊天室①

聊天室服务器: 创建项目 桌面不需要使用控件 Program.cs internal class Program {static TcpListener server;[STAThread]static void Main(){Program p new Program(); p.start();}void start(){server new TcpListener(IPAddress.Parse(GetIP()), 33…

WINUI——CommunityToolkit.Mvvm Messenger接收消息时报错:Cannot access a disposed object.

背景 WINUI开发时使用CommunityToolkit.Mvvm的Messemger让UI展示一些信息时出现错误: System.ObjectDisposedException:“Cannot access a disposed object. ObjectDisposed_ObjectName_Name” 详细见下述截图: 开发环境 WIN11 WINUI3 …

【源码】html+JS实现:24小时折线进度图

<!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta name"viewport" content"widthdevice-width, initial-scale1.0"> <title>24小时折线进度图</title> <st…

代码生成-CodeGeeX2本地部署体验

一 CodeGeeX2介绍&#xff1a; CodeGeeX2 是多语言代码生成模型 CodeGeeX (KDD’23) 的第二代模型。不同于一代 CodeGeeX&#xff08;完全在国产华为昇腾芯片平台训练&#xff09; &#xff0c;CodeGeeX2 是基于 ChatGLM2 架构加入代码预训练实现&#xff0c;得益于 ChatGLM2 的…

是否可以购买外链?

答案是可以&#xff0c;但要看你买什么外链&#xff0c;有价值的自然外链价格肯定也高&#xff0c;随便到某些平台发的外链&#xff0c;哪怕是相关的高权重平台&#xff0c;作用也有限&#xff0c;当然&#xff0c;你要大批量购买&#xff0c;说不定也能出一点效果&#xff0c;…

天诚公租房、人才公寓NB-IOT人脸物联网智能门锁解决方案

近期&#xff0c;全国已有超70城推出商品房“以旧换新”。各地商品房“以旧换新”主要采取国企收购、市场联动、税费补贴三种模式&#xff0c;二手房和新房市场交易活跃度均有提升。 一、人才公寓掀起建设浪潮 事实上&#xff0c;旧房被收购后将被纳入保障性租赁住房&#xf…

opencv 通过滑动条调整阈值处理、边缘检测、轮廓检测、模糊、色调调整和对比度增强参数 并实时预览效果

使用PySimpleGUI库创建了一个图形用户界面(GUI),用于实时处理来自OpenCV摄像头的图像。它允许用户应用不同的图像处理效果,如阈值处理、边缘检测、轮廓检测、模糊、色调调整和对比度增强。用户可以通过滑动条调整相关参数。 完整代码在文章最后,可以运行已经测试; 代码的…

代码随想录Day58

392.判断子序列 题目&#xff1a;392. 判断子序列 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a;定义重合数记录s与t的比对情况&#xff0c;挨个取出t的字符&#xff0c;与s的字符进行比较&#xff0c;如果相同&#xff0c;重合数就加1&#xff0c;跳到s的下一个字…

QStyledItemDelegate的使用方法

QStyledItemDelegate 是 Qt 框架中用于为模型/视图框架提供数据项显示和编辑的一个类。 1. 创建 QStyledItemDelegate 实例 通常&#xff0c;你不需要直接实例化 QStyledItemDelegate&#xff0c;因为它是默认的委托。但如果你需要自定义显示和编辑行为&#xff0c;你可以继承…

韩顺平0基础学java——第22天

p441-459 异常exception 选中代码块&#xff0c;快捷键ctraltt6&#xff0c;即trt-catch 如果进行了异常处理&#xff0c;那么即使出现了异常&#xff0c;但是会继续执行 程序过程中发生的异常事件分为两大类&#xff1a; 异常体系图※ 常见的运行异常&#xff1a;类型转换…

继承深度剖析

前言 从继承开始就开始C进阶了&#xff0c; 这一块需要好好学习&#xff0c;这块知识很重要&#xff0c; 坑有点多&#xff0c;所以是面试笔试的常客。 基本概念 继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段&#xff0c; 它允许程序员在保持原有…

使用MNIST数据集训练手写数字识别模型

一、MNIST数据集介绍 MNIST 数据集&#xff08;手写数字数据集&#xff09;是一个公开的公共数据集&#xff0c;任何人都可以免费获取它。目前&#xff0c;它已经是一个作为机器学习入门的通用性特别强的数据集之一&#xff0c;所以对于想要学习机器学习分类的、深度神经网络分…

抓包工具 Wireshark 的下载、安装、使用、快捷键

目录 一、什么是Wireshark&#xff1f;二、Wireshark下载三、Wireshark安装四、Wireshark使用4.1 基本使用4.2 过滤设置1&#xff09;捕获过滤器2&#xff09;显示过滤器 4.3 过滤规则1&#xff09;捕获过滤器-规则语法2&#xff09;显示过滤器-规则语法 4.4 常用的显示过滤器规…

js实现一个数据结构——栈

栈的概念就不再赘述&#xff0c;无可厚非的先进后出&#xff0c;而JS又是高级语言&#xff0c;数组中的方法十分丰富&#xff0c;已经自带了push pop方法进行入栈出栈的操作。 1.基本实现 class Stack {constructor() {this.items [];}// 入栈push(item) {this.items.push(i…

【C++入门(1)】命名空间

一、C出世 我们先简单认识下C的来历&#xff0c;C是在C语言的基础上发展来的。 当年C的设计者Bjarne Stroustrup&#xff0c;本贾尼斯特劳斯特卢普先生设计C语言之初&#xff0c;是为了对C语言做出一些更改&#xff0c;弥补C语言在一些方面的不足&#xff0c;或者做出其他的设…

二阶段提交(2pc)协议

二阶段提交&#xff08;2pc&#xff09;协议 1、 简介 二阶段提交算法是一个分布式一致性算法&#xff0c;强一致、中心化的原子提交协议&#xff0c;主要用来解决分布式事务问题。在单体spring应用中我们往往通过一个Transactional注解就可以保证方法的事务性&#xff0c;但…

破解发展难题 台山这家合作社以农业社会化服务助推乡村振兴

风吹稻田千层浪&#xff0c;眼下&#xff0c;台山四九镇的早稻长势喜人&#xff0c;沉甸甸的稻穗迎风而动&#xff0c;已进入破口抽穗的关键期&#xff0c;即将在6月底陆续迎来丰收。在台山市明华汇种养专业合作社管理的稻田里&#xff0c;合作社负责人梁明喜正仔细观察着稻苗的…

算法第六天:力扣第977题有序数组的平方

一、977.有序数组的平方的链接与题目描述 977. 有序数组的平方的链接如下所示&#xff1a;https://leetcode.cn/problems/squares-of-a-sorted-array/description/https://leetcode.cn/problems/squares-of-a-sorted-array/description/ 给你一个按 非递减顺序 排序的整数数组…