Python 程序慢的像蜗牛,我该怎么办?
1.
“一猿小讲”的风格就是多元化,偶尔会真情吐露一下程序猿的内心;偶尔也结合自己的经历畅聊一些经验杂谈;其中也不乏幽默风趣的技术故事。分享是件快乐的事情,工作之余,有时间我就尽力多码字,多推几篇文章。其实讲真,我每次都是抱着分享给那些需要的人,说不定哪篇文章,就戳中了你,扣开了你的心扉,解决了你的困惑。
好了,不扯啦,言归正传,不跑偏。请准备好小板凳,我们的分享开始。
2.
经常理财投资的都清楚,投资的产品周期大概分为 12 个月、24 个月、36 个月。记得上次在信用风险模型项目实现中,为了跑信用风险模型,按照业务要求,需要按照产品周期的维度进行数据逐条拆分、衍生、细化。
站在技术的视角,其实需要针对每条数据,统一执行一个函数,未曾想 Python 天然提供 apply 函数,当时也没管三七二十一,直接拿来主义上来就是用。但是程序跑起来,由于数据量大的原因,一个进程一条一条去执行数据。等输出结果,真是在线等的好着急,就这样程序跑了一整天,苦苦的等出来了结果,你可能不相信,我居然能忍受这么慢的程序,连我自己都不敢相信。
不过当拿到跑出来的结果,却有点不尽人意,于是业务要求加大数据量。但是我的程序这么慢,如果加大数据量,程序跑起来,如果再死等程序的结果,到最后就只能变成了等死啦。
没法,只有技术可以治愈金融危机的创伤;只有技术才能让业务更美好;IT优化没有终点,极致体验没有尽头。那我只能再考虑如何优化一下代码,提升一下程序性能。再三思索,最后决定采取多进程的方式进行了调整。其实和吃包子是一样式的,想想一个人吃 10 个包子和 5 个人吃 10 个包子,那场面效果能一样吗?不过调整后的程序,运行效率确实大幅提升。
唯恐你们也再纠结此种问题,为了你们不再入坑,省出更多时间冲咖啡。作为一个负责任分享的我,岂能只截一张图给你们,还是从实际项目中简单抽取一个 demo 雏形出来,以备你们的不时之需。
if __name__ == '__main__':
# 把36期的数据按照50000条进行分割成小文件
step = split_36_months()
# 注意:采用多进程进行执行,不然真的会很慢呦
# 一个进程处理一个36期的小 csv 文件,进行按照6个月的维度进行细分
p = Pool()
for i in range(1, step + 1):
p.apply_async(add_months_36_months, args=(i,))
print('等待所有36期数据处理的子进程执行完毕...')
p.close()
p.join()
print('所有36期数据处理的子进程执行完成')
然后定义 split_36_months 函数,完成大的 csv 文件拆分成小 csv 文件。
# 把36期的csv文件拆分成若干小文件
def split_36_months():
# TODO 把csv文件拆分成小文件
# TODO 统计拆分的小文件个数,这里假设拆分成为5个小文件
return 5
接着定义 add_months_36_months 函数,完成数据的业务处理(函数名不重要,函数名能起成这样,也是人才,不过这也不是一时的事情,是历史迭代,所以各位看官,莫纠结,莫纠结,莫纠结)。
# 36期的数据逐个以6个月的维度进行拆分
def add_months_36_months(step):
print('step: {0} 进程ID:{1} 开始执行任务'.format(step, os.getpid()))
# TODO 针对每条数据执行apply函数
# chunk = chunk.apply(add_months, axis=1, periods=(36 + 1))
# print("step:{0}-{1}月份处理完成".format(step, count)) # chunk = chunk.apply(format_reserve_tm, axis=1)
# print("step:{0}-{1}开始格式化还款日期".format(step, count))
# TODO 把执行结果输出到csv文件中
print("step:{0} 进程ID: {1} 任务处理完毕".format(step, os.getpgid()))
代码码完了,真金不怕火炼,效果不怕检验,是骡子是马总要牵出来遛一遛。程序运行效果如预期所料,拆分成5个小文件,然后每个文件对应一个进程去完成业务数据处理,着实不错。
但是知其然,知其所以然,容我再多絮叨两句。
第一步:创建进程池。Python 中如果要启动大量的子进程,那么就可以用进程池的方式批量创建子进程。
p = Pool() #默认进程数量是CPU的核数
p = Pool(5) #创建拥有5个进程数量的进程池
第二步:执行子进程。
p.apply_async(add_months_36_months, args=(i,))
第三步:告诉主进程,你等着所有子进程运行完毕后在运行剩余部分。
p.close() #关闭进程池
p.join() #等待所有工作进程退出
友情提示:对 Pool 对象调用 join() 方法会等待所有子进程执行完毕;调用 join() 之前必须先调用 close(),调用 close() 之后就不能继续添加新的 Process 了。
3.
好了,程序从慢到快的步骤只需要一步,那就是实现思路的转变。今天的分享就到这儿,希望对你有帮助。

Python 程序慢的像蜗牛,我该怎么办?的更多相关文章
- 运行python程序
1 在windows下运行python程序 1)从DOS命令行运行python脚本 用python解释器来执行python脚本,在windows下面python解释器是python.exe,我的pyt ...
- 【python之路2】CMD中执行python程序中文显示乱码
在IDLE中执行下面代码,中文显示正常: # -*- coding:utf-8 -*- st=raw_input("请输入内容")print st 但在CMD中执行e:\hello ...
- Python程序高效地调试
现在我在debug python程序就只是简单在有可能错误的地方print出来看一下,不知道python有没像c++的一些IDE一样有单步调试这类的工具?或者说各位python大神一般是怎么debug ...
- python学习笔记-python程序运行
小白初学python,写下自己的一些想法.大神请忽略. 安装python编辑器,并配置环境(见http://www.cnblogs.com/lynn-li/p/5885001.html中 python ...
- python程序一直在后台运行的解决办法
刚写了个python程序,要一直在后台运行,即使断开ssh进程也在,下面是解决办法: 假如Python程序为test.py 编写shell脚本start.sh #!/bin/bash python t ...
- 第一个python程序
一个python程序的两种执行方式: 1.第一种方式是通过python解释器: cmd->python->进入python解释器->编写python代码->回车. 2.第二种方 ...
- Python程序的首行
>问题 >>在一些python程序中的首行往往能够看见下面这两行语句中的一句 >>>#!/usr/bin/Python >>>#!/usr/bin ...
- Python程序员的进化史
各种程序员所写的阶乘算法代码 # -*- coding: utf-8 -*- #新手程序员(递归) def factorial(x): if x == 0: return 1 else: return ...
- Python程序的常见错误(收集篇)
关于Python Python是一门解释性的,面向对象的,并具有动态语义的高级编程语言.它高级的内置数据结构,结合其动态类型和动态绑定的特性,使得它在快速应用程序开发(Rapid Applicatio ...
随机推荐
- 前端解决跨域问题的终极武器——Nginx反向代理
提到代理,分为:正向代理和反向代理. 正向代理:就是你访问不了Google,但是国外有个VPN可以访问Google,你访问VPN后叫它访问Google,然后把数据传给你. 正向代理隐藏了真实的客户端. ...
- 异常 context 包的扫描
异常信息: org.xml.sax.SAXParseException; lineNumber: 7; columnNumber: 55; schema_reference.4: 无法读取方案文档 ' ...
- ubuntu16.04 + caffe + SSD + gpu 安装
昨天我们买好了硬件,今天我们开始安装caffe了,我本人安装过caffe不下10次,每次都是一大堆问题,后来终于总结了关键要点,就是操作系统. 1. 千万不要用ubuntu17.10来安装, 2. 最 ...
- js中字符串 stringObject 的 replace() 方法
一.定义 replace() 方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的字符串. 二.语法 stringObject.replace(regexp/substr,repl ...
- 《自拍教程46》Python_adb自动拍照100张
Android手机测试, 涉及照相机(Camera)应用程序的稳定性测试的用例, 需要涉及100张照片的拍照自动化测试. 准备阶段 先清理老照片,照片一般存放在/scard/DCIM目录下 adb s ...
- 使用 C# 和 OpenGL (SharpGL) 实现的一个简易画图版
原文地址:https://billc.io/2019/10/fpainter/ 计算机图形学的第一个大作业是用 OpenGL 或 DirectX3d 实现一个平面的画图,应当具备直线和圆形的功能.正好 ...
- 【Weiss】【第03章】练习3.11:比较单链表递归与非递归查找元素
[练习3.11] 编写查找一个单链表特定元素的程序.分别用递归和非递归实现,并比较它们的运行时间. 链表必须达到多大才能使得使用递归的程序崩溃? Answer: 实现都是比较容易的,但是实际上查找链表 ...
- Python下载各种功能包出问题
问题详情 点击之后出现 AttributeError: module 'importlib._bootstrap' has no attribute 'SourceFileLoader' 解决方法 c ...
- Java14来了!Switch竟如此简单?Lombok也不需要了?来使用Idea配置Java14的开发环境吧!
Java 14 在 2020.3.17 日发布正式版了,但现在很多公司还在使用 Java 7 或 Java 8,每当看到 Java 又发布新版本心里就慌得一匹.不过此版本并不是 LTS (长期支持版) ...
- Fast and accurate bacterial species identification in urine specimens using LC-MS/MS mass spectrometry and machine learning (解读人:闫克强)
文献名:Fast and accurate bacterial species identification in urine specimens using LC-MS/MS mass spectr ...