有没有简单的方法来基准python脚本?(Is there any simple way to be

2019-08-21 09:03发布

通常我使用shell命令time 。 我的目的是测试数据是小型,中型,大型或超大型集,大量的时间和内存使用情况将会如何。

对于Linux或只是蟒蛇的任何工具来做到这一点?

Answer 1:

看一看timeit , 蟒蛇探查和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"))

从本质上讲,你可以通过它Python代码作为字符串参数,它会在指定的时间量运行,并打印执行时间。 从文档中的重要位:

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

创建一个Timer与给定的说法, 安装代码和定时器功能实例和运行其timeit与执行次数的方法。

...和:

Timer.timeit(number=1000000)

主要发言时间执行次数 。 此执行建立语句一次,然后返回它需要执行该主声明的次数,以秒计,为浮动的时间。 这个论点是次通过循环违约一百万的数量。 主要的声明,建立语句和定时器功能使用传递给构造函数。

注意

默认情况下, timeit暂时关闭garbage collection的时间期间。 这种方法的优点是,它使独立计时更具有可比性。 这个缺点是,GC可以是正被测量的功能的性能的重要组成部分。 如果是这样,GC可以重新启用如设置字符串的第一个语句。 例如:

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创建类似下面的调用图:

你可以很容易地看到哪些路径的颜色使用了大部分时间。 您可以创建它们使用pycallgraph API,或者使用一个包装脚本:

pycallgraph graphviz -- ./mypythonscript.py

开销是相当可观的,虽然。 因此,对于已经长期运行的进程,创建图形可能需要一些时间。



Answer 2:

我用一个简单的装饰,以时间FUNC

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


Answer 3:

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

这是基准的原始排序,但它的不够好。



Answer 4:

我通常做一个快速的time ./script.py ,看看需要多长时间。 这可能没有什么给你的记忆,至少不会作为默认值。 您可以使用/usr/bin/time -v ./script.py获得了大量的信息,包括内存使用。



Answer 5:

看看鼻子 ,并在其插件之一, 这其中尤其如此。

一旦安装,鼻子是在你的路径中的脚本,你可以在其中包含了一些Python脚本目录拨打:

$: nosetests

这看起来在当前目录下的所有Python文件并且将执行它识别为一个测试的任何功能:例如,它承认在其名称中的TEST_作为测试的任何功能。

所以,你可以创建一个名为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

和读取配置文件,可以使用这条巨蟒行:

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


Answer 6:

内存分析器的所有内存需求。

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

运行安装点子:

pip install memory_profiler

导入库:

import memory_profiler

一个装饰添加到您要分析的项目:

@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

实例为从文档,上面链接。



Answer 7:

要当心timeit是很慢的,它需要12第二开我的媒体处理器,只是初始化(或者运行功能)。 您可以测试这个公认的答案

def test():
    lst = []
    for i in range(100):
        lst.append(i)

if __name__ == '__main__':
    import timeit
    print(timeit.timeit("test()", setup="from __main__ import test")) # 12 second

对于简单的事情,我会用time来代替,我的电脑上它返回的结果0.0

import time

def test():
    lst = []
    for i in range(100):
        lst.append(i)

t1 = time.time()

test()

result = time.time() - t1
print(result) # 0.000000xxxx


Answer 8:

最简单的方法来快速测试的任何功能是使用此语法: %timeit my_code

例如 :

%timeit a = 1

13.4 ns ± 0.781 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)


文章来源: Is there any simple way to benchmark python script?