牛牛逼逼叉叉
菜单

分析 Python 脚本

2015年03月08日,分类《编程学习》,作者:
博客捐助

本文的原文是:Profiling Python Scripts

我有一个负责一个长期运行任务的 Python 脚本。这个脚本同其他三个系统通信 – 它从系统 #1 和 #2 读取数据,合并它们然后再把它们推送到系统 #3。这是下面的描述。问题是迁移运行在我不满意的一个地方。因为我想知道该脚本的大部分工作是在与哪个慢的外部系统进行通信。Python 有一个非常好用的内建的分析器来回答这类问题。按照这篇文章来学习如何使用它。

2015-01-communications

分析器(Profiler)

基础用法非常简单。假设你有一个 myscript.py。使用 profiler 运行它,你需要做的是:

$ python -m cProfile -o profile.out myscript.py <other-args>

它将运行这个脚本并且 dump 这个 debug 数据到 profile.out。你也可以省略 -o profile.out 来让统计的 dumped 到脚本最后的 stdout。

Subprocesses

如果你的脚本使用了任何 subprocesses,事情就会变得有点复杂。以我来说,我对脚本的主流程不感兴趣 – 它所做的所有事情就是派生(spawn)一些 worker 子进程。我感兴趣的是在 worker 中发生了什么。

2015-01-workers

让我们假设你的代码与此类似:

import multiprocessing
import time

def worker(num):
    time.sleep(3)
    print 'Worker:', num

if __name__ == '__main__':
    for i in range(5):
        p = multiprocessing.Process(target=worker, args=(i,))
        p.start()

你需要引入另外一个间接层:

import multiprocessing
import cProfile
import time

def worker(num):
    time.sleep(3)
    print 'Worker:', num

def profile_worker(num):
    cProfile.runctx('test(num)', globals(), locals(), 'profile-%d.out' %num)


if __name__ == '__main__':
    for i in range(5):
        p = multiprocessing.Process(target=profile_worker, args=(i,))
        p.start()

就是这样。这个脚本运行之后,你将得到 profile-0.outprofile-4.out 这4个文件。

读取分析数据

如果你忽略 -o profile.out 这时将在 stdout 得到统计数据。这不是一个完美的解决方案。更好的解决方案是把数据 dump 到文件中然后使用 runsnake 来分析它。为了在 ubuntu 上安装它,你需要 wxpython 包,然后你才可以使用 easy-install 安装它。

$ sudo apt-get install python-wxgtk2.8 python-wxtools wx2.8-doc wx2.8-examples wx2.8-headers wx2.8-i18n
$ sudo easy-install SquareMap RunSnakeRun

由于某种原因我没有在 virtualenv 中运行工作。我需要一个全系统的 easy-install。有人抱怨缺失了 wx 模块。我的系统是 ubuntu 12.04。

然后,就很简单了:

$ runsnake profile.out

你在不同的函数获得了很好的统计分析,调用次数和累计时间。这些数据可以告诉你关于你 app 的很多东西。以我而言我获悉了与其中一个系统通信花费了 90% 的时间。从那里开始我可以优化它。

2015-01-runsnake

来源



发表评论

电子邮件地址不会被公开。 必填项已用*标注

【上一篇】

Chrome 控制台console的用法(学了之后对于调试js可是大大有用的哦)

【下一篇】

移动H5前端性能优化指南