有没有简单的方法来testingpython脚本?

通常我使用shell命令time 。 我的目的是testing数据是小的,中等的,大的还是非常大的集合,多less时间和内存的使用情况。

任何工具为Linux或只是Python来做到这一点?

看看timeit , python profiler和pycallgraph 。

timeit

 def test(): """Stupid test function""" lst = [] for i in range(100): lst.append(i) if __name__ == '__main__': import timeit print(timeit.timeit("test()", setup="from __main__ import test")) 

本质上,您可以将它作为一个stringparameter passing给python代码,它将在指定的时间内运行并打印执行时间。 文档中的重要部分:

timeit.timeit(stmt='pass', setup='pass', timer=<default timer>, number=1000000)

用给定的语句, 设置代码和定时器函数创build一个Timer实例,并运行带有数字执行的timeit方法。

…和:

Timer.timeit(number=1000000)

主要语句的时间编号执行。 这会执行一次setup语句,然后返回多次执行main语句所花费的时间,以秒为单位进行度量。 论点是循环次数,默认为100万。 主语句,设置语句和要使用的定时器函数被传递给构造函数。

注意

默认情况下, timeit暂时closuresgarbage collection 。 这种方法的优点是使独立的时间更具可比性。 这个缺点是GC可能是被测function性能的重要组成部分。 如果是这样,可以重新启用GC作为安装string中的第一条语句。 例如:

timeit.Timer('for i in xrange(10): oct(i)', 'gc.enable()').timeit()

剖析

分析会给你一个更详细的想法。 以下是官方文档中的“即时示例”:

 import cProfile import re cProfile.run('re.compile("foo|bar")') 

哪个会给你:

  197 function calls (192 primitive calls) in 0.002 seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 1 0.000 0.000 0.001 0.001 <string>:1(<module>) 1 0.000 0.000 0.001 0.001 re.py:212(compile) 1 0.000 0.000 0.001 0.001 re.py:268(_compile) 1 0.000 0.000 0.000 0.000 sre_compile.py:172(_compile_charset) 1 0.000 0.000 0.000 0.000 sre_compile.py:201(_optimize_charset) 4 0.000 0.000 0.000 0.000 sre_compile.py:25(_identityfunction) 3/1 0.000 0.000 0.000 0.000 sre_compile.py:33(_compile) 

这两个模块应该给你一个关于在哪里寻找瓶颈的想法。

此外,要掌握profile的输出,看看这个职位

pycallgraph

该模块使用graphviz来创build如下的调用图:

callgraph示例

您可以通过颜色轻松查看哪些path最耗时。 您可以使用pycallgraph API或使用打包的脚本创build它们:

 pycallgraph graphviz -- ./mypythonscript.py 

虽然开销是相当可观的。 因此,对于已经很长时间运行的stream程,创build图表需要一些时间。

我使用一个简单的装饰器来定时function

 def st_time(func): """ st decorator to calculate the total time of a func """ def st_func(*args, **keyArgs): t1 = time.time() r = func(*args, **keyArgs) t2 = time.time() print "Function=%s, Time=%s" % (func.__name__, t2 - t1) return r return st_func 

我通常会快速地time ./script.py来查看需要多长时间。 这并不显示你的内存,但至less不是默认的。 您可以使用/usr/bin/time -v ./script.py来获取大量信息,包括内存使用情况。

timeit模块很慢很奇怪,所以我写了这个:

 def timereps(reps, func): from time import time start = time() for i in range(0, reps): func() end = time() return (end - start) / reps 

例:

 import os listdir_time = timereps(10000, lambda: os.listdir('/')) print "python can do %d os.listdir('/') per second" % (1 / listdir_time) 

对我来说,它说:

 python can do 40925 os.listdir('/') per second 

这是一种原始的基准testing,但已经足够好了。

看一下鼻子和它的一个插件,特别是这个插件。

一旦安装,鼻子就是你的path中的脚本,你可以调用一个包含一些python脚本的目录:

 $: nosetests 

这将在当前目录中的所有python文件中查找,并执行它认为是testing的任何函数:例如,它可以识别其名称中包含单词test_的任何函数作为testing。

所以你可以创build一个名为test_yourfunction.py的python脚本,并在其中写下如下内容:

 $: cat > test_yourfunction.py def test_smallinput(): yourfunction(smallinput) def test_mediuminput(): yourfunction(mediuminput) def test_largeinput(): yourfunction(largeinput) 

那么你必须跑步

 $: nosetest --with-profile --profile-stats-file yourstatsprofile.prof testyourfunction.py 

并阅读configuration文件,使用这个python行:

 python -c "import hotshot.stats ; stats = hotshot.stats.load('yourstatsprofile.prof') ; stats.sort_stats('time', 'calls') ; stats.print_stats(200)" 

内存分析器满足您所有的内存需求。

https://pypi.python.org/pypi/memory_profiler

运行一个点子安装:

 pip install memory_profiler 

导入库:

 import memory_profiler 

添加一个装饰器到你想要的configuration文件:

 @profile def my_func(): a = [1] * (10 ** 6) b = [2] * (2 * 10 ** 7) del b return a if __name__ == '__main__': my_func() 

执行代码:

 python -m memory_profiler example.py 

接收输出:

  Line # Mem usage Increment Line Contents ============================================== 3 @profile 4 5.97 MB 0.00 MB def my_func(): 5 13.61 MB 7.64 MB a = [1] * (10 ** 6) 6 166.20 MB 152.59 MB b = [2] * (2 * 10 ** 7) 7 13.61 MB -152.59 MB del b 8 13.61 MB 0.00 MB return a 

示例来自上面链接的文档。