哪个网站可以做行程表,网站建设规划表,怎样建网站赚钱,微信官方公众号前言
继续解决问题
慢
一个服务运行有点慢#xff0c;当然 Python 本身不快#xff0c;如果再编码不当那这个可能就是量级上的劣化。 整个 Code 主线逻辑 1700#xff0c;各依赖封装 3000#xff0c;主线逻辑也是很久远的痕迹#xff0c;长函数都很难看清楚一个 if els…前言
继续解决问题
慢
一个服务运行有点慢当然 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(rsome_pattern, text_str)if search_objects:objects search_objects.group.split(; )for obj in objects:# do somethingpassdef 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, LocalManagerlocal_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 是茫茫多的信息量得空再细说吧。