不知道程序哪里掉链子?看看如何定位Python程序性能瓶颈

论坛 期权论坛 期权     
真格量化   2019-7-11 08:26   4753   0
对于简单的Python程序,我们很容易知道运行的速度瓶颈所在,而对于复杂的程序,定位性能瓶颈就颇费功夫。




对Python代码优化的前提是需要了解性能瓶颈在什么地方,程序运行的主要时间是消耗在哪里,好在应付复杂的代码我们可以借助一些工具来定位。Python 内置了丰富的性能分析工具,如 profile,cProfile 与 hotshot 等。其中 Profiler 是 Python 自带的一组程序,能够描述程序运行时候的性能,并提供各种统计帮助用户定位程序的性能瓶颈。Python 标准模块提供三种 profilers:cProfile,profile 以及 hotshot。


profile 的使用非常简单,只需要在使用之前进行 import 即可。具体实例如下:



程序的运行结果如下:



其中输出每列的具体解释如下:

  • ncalls:表示函数调用的次数;
  • tottime:表示指定函数的总的运行时间,除掉函数中调用子函数的运行时间;
  • percall:(第一个 percall)等于 tottime/ncalls;
  • cumtime:表示该函数及其所有子函数的调用运行的时间,即函数开始调用到返回的时间;
  • percall:(第二个 percall)即函数运行一次的平均时间,等于 cumtime/ncalls;
  • filename:lineno(function):每个函数调用的具体信息;


如果需要将输出以日志的形式保存,只需要在调用的时候加入另外一个参数。如 profile.run("profileTest()","testprof")。

对于 profile 的剖析数据,如果以二进制文件的时候保存结果的时候,可以通过 pstats 模块进行文本报表分析,它支持多种形式的报表输出,是文本界面下一个较为实用的工具。使用非常简单:

其中 sort_stats() 方法能够对剖分数据进行排序, 可以接受多个排序字段,如 sort_stats('name', 'file') 将首先按照函数名称进行排序,然后再按照文件名进行排序。常见的排序字段有 calls( 被调用的次数 ),time(函数内部运行时间),cumulative(运行的总时间)等。此外 pstats 也提供了命令行交互工具,执行 python – m pstats 后可以通过 help 了解更多使用方式。


对于大型应用程序,如果能够将性能分析的结果以图形的方式呈现,将会非常实用和直观,常见的可视化工具有 Gprof2Dot,visualpytune,KCacheGrind 等。



Python 性能优化工具


Python 性能优化除了改进算法,选用合适的数据结构之外,还有几种关键的技术,比如将关键 Python 代码部分重写成 C 扩展模块,或者选用在性能上更为优化的解释器等,这些在本文中统称为优化工具。python 有很多自带的优化工具,如 Psyco,Pypy,Cython,Pyrex 等,这些优化工具各有千秋,本节选择几种进行介绍。


Pypy


PyPy 表示 "用 Python 实现的 Python",但实际上它是使用一个称为 RPython 的 Python 子集实现的,能够将 Python 代码转成 C, .NET, Java 等语言和平台的代码。PyPy 集成了一种即时 (JIT) 编译器。和许多编译器、解释器不同,它不关心 Python 代码的词法分析和语法树。因为它是用 Python 语言写的,所以它直接利用 Python 语言的 Code Object。Code Object 是 Python 字节码的表示,也就是说, PyPy 直接分析 Python 代码所对应的字节码 ,这些字节码即不是以字符形式也不是以某种二进制格式保存在文件中, 而在 Python 运行环境中。


比如对于这样一个循环:

使用 python 和 pypy 分别运行,得到的运行结果分别如下:



可见使用 pypy 来编译和运行程序,其效率大大提高。


Cython


Cython 是用 python 实现的一种语言,可以用来写 python 扩展,用它写出来的库都可以通过 import 来载入,性能上比 python 的快。cython 里可以载入 python 扩展 ( 比如 import math),也可以载入 c 的库的头文件 ( 比如 :cdef extern from "math.h"),另外也可以用它来写 python 代码。将关键部分重写成 C 扩展模块。


Cython 代码与 Python 不同,必须先编译,编译一般需要经过两个阶段,将 pyx 文件编译为 .c 文件,再将 .c 文件编译为 .so 文件。编译完成之后可以导入到 Python 中使用。


一般来说,Python程序中的大部分代码不需要进行性能优化,因为其并不进行繁重的运算,可能只有几个关键的运算部分可以尝试用Cython优化。开发者可以逐渐将这些“性能热点”转换为Cython,从而获得最明显的性能提升。程序的其余部分可以原样保留在Python中,以方便其他开发人员理解和改动。

内容来源:http://news.51cto.com/art/201802/566645.htm

— — — — — — E N D — — — — — —
往期文章:
Numpy处理tick级别数据技巧
真正赚钱的期权策略曲线是这样的
多品种历史波动率计算
如何实现全市场自动盯盘
AI是怎样看懂研报的
真格量化策略debug秘籍
真格量化对接实盘交易
常见高频交易策略简介

如何用撤单函数改进套利成交

Deque提高处理队列效率

策略编程选Python还是C++

如何用Python继承机制节约代码量

十大机器学习算法
如何调用策略附件数据

如何使用智能单

如何扫描全市场跨月价差

如何筛选策略最适合的品种

活用订单类型规避频繁撤单风险

真格量化回测撮合机制简介

如何调用外部数据

如何处理回测与实盘差别

如何利用趋势必然终结获利

常见量化策略介绍

期权交易“七宗罪”

波动率交易介绍

推高波动率的因素

波动率的预测之道

趋势交易面临挑战
如何构建知识图谱
机器学习就是现代统计学

AI技术在金融行业的应用

如何避免模型过拟合

低延迟交易介绍

架构设计中的编程范式

交易所视角下的套利指令撮合

距离概念与特征识别

气象风险与天气衍生品

设计量化策略的七个“大坑”

云计算在金融行业的应用

机器学习模型评估方法
真格量化制作期权HV-IV价差
另类数据介绍

TensorFlow中的Tensor是什么?

机器学习的经验之谈

用yfinance调用雅虎财经数据

容器技术如何改进交易系统
Python调用C++
如何选择数据库代理
统计套利揭秘
[h1]一个Call搅动市场?让我们温习一下波动率策略[/h1][h1]如何用真格量化设计持仓排名跟踪策略[/h1][h1]还不理解真格量化API设计?我们不妨参考一下CTP平台[/h1][h1]理解同步、异步、阻塞与非阻塞[/h1][h1]隐波相关系数和偏度——高维风险的守望者[/h1]Delta中性还不够?——看看如何设计Gamma中性期权策略
[h1]Python的多线程和多进程——从一个爬虫任务谈起[/h1]线程与进程的区别皮尔逊相关系数与历史K线匹配
Python2和Python3的兼容写法Python代码优化技巧
理解Python的上下文管理器
如何写出更好的Python代码?这是Python软件基金会的建议[/url]
[url=http://mp.weixin.qq.com/s?__biz=MzU4OTg0NjkyOA==&mid=2247484166&idx=1&sn=88003c01744692c15637d35f54a8d693&chksm=fdc603f9cab18aef2d0b3feb38a32cdc8b4a42b880ec02f27e1b657f31c964240d9cb51d6bd4&scene=21#wechat_redirect]评估程序化模型时我们容易忽视的指标
[/url][url=http://mp.weixin.qq.com/s?__biz=MzU4OTg0NjkyOA==&mid=2247484148&idx=1&sn=8fbf3c0debe17000462d64d9fd26aaf4&chksm=fdc6020bcab18b1dcde5a4da2d9c68a308f24ac9078fd7e59736eeaec4ad73146227e3fe4fec&scene=21#wechat_redirect]




真格量化可访问:
https://quant.pobo.net.cn


真格量化微信公众号,长按关注:

遇到了技术问题?欢迎加入真格量化Python技术交流QQ群  726895887


































分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:870
帖子:180
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP