美文网首页
IPython中的开发工具(二)

IPython中的开发工具(二)

作者: 5f2a6061653d | 来源:发表于2018-08-13 21:53 被阅读128次

    代码运行时间分析工具

    在现实生活中存在更大规模、运行时间更长的数据分析应用程序,因此当希望测试各部分代码、函数调用或语句的执行时间时,当希望了解某个复杂计算过程中占用时间最长的函数时,IPython中的代码运行时间分析工具可轻松解决。

    之前所讲解的%time%timeit两个魔术命令就是IPython中代码运行时间分析的重要工具,具体使用如下图所示。

    %time作不同函数执行时间分析.jpg
    图中f1方法执行时间(Wall time)为270ms,而f2方法只用了78ms,二者相差三倍有余,但Wall time在不同时间执行会有不同结果,因此需要使用更精准的魔术命令%timeit来执行,如下图所示。
    %timeit作不同函数执行时间分析.jpg
    图中In[6]是对方法f1进行多次执行取平均值为125ms±1.84msIn[7]是对方法f2进行多次执行取平均值为71.7ms±774μs%timeit计算的函数执行时间更为精准。对于数据分析来说,尤其是大型数据分析应用程序,看似微小的时间差距,在后期的数据执行中都会不断地累积,从而影响整个程序的执行效率。

    代码性能分析工具

    代码性能分析与上节讲解的代码执行时间息息相关,执行时间的快慢直接影响整个程序的性能,其中IPython主要的性能分析工具是cProfile模块,但它不是专门为IPython而设计的。cProfile在程序或代码块执行时会记录程序或代码块中各函数执行所耗费的时间。

    cProfile一般在命令行中使用,最终将执行整个程序并输出函数的执行时间,具体如下所示。

    在循环中执行线性代数计算(计算一个200×200的矩阵的最大本征值绝对值)

     import numpy as np
     from numpy.linalg import eigvals
     def xrange(x):
         return iter(range(x))
     def run_experiment(niter=200):
         K = 200
         results = []
         for _ in xrange(niter):
             mat = np.random.randn(K, K)
             max_eigenvalue = np.abs(eigvals(mat)).max()
             results.append(max_eigenvalue)
         return results
     some_results = run_experiment()
     print ('Largest one we saw: %s' % np.max(some_results))
    

    使用cProfile执行代码(代码保存为2.py),执行命令为:python -m cProfile 2.py。执行(在PyCharm的Terminal中)结果如下图所示。

    cProfile执行结果.jpg
    图只是输出结果的一部分,可看出各函数在此次执行过程中所耗费的总时间(cumtime),cProfile记录的是各函数从调用开始到结束的时间,不考虑调用期间是否调用其他函数,即调用其他函数时也不会停止计时,并最终计算总时间。

    上述运行结果不能直观的知道耗费时间最多的函数,若要更直观的查看时间,可以使用命令:python -m cProfile -s cumulative 2.py,此命令是以cumulative time为基准进行排序输出,因此可以清楚地查看耗费时间由高到低的函数,执行结果如下图所示。

    按cumulative time排序输出.jpg
    上述内容是讲解命令行使用cProfilecProfile还能以编程的方式来分析任意代码块的性能,其中IPython就为此提供了一个方便的接口——%prun和带-p%run%prun虽然与cProfile格式类似,但分析的内容有所不同,%prun分析的是Python语句而不是整个.py文件,使用命令为:%prun -l 7 -s cumulative run_experiment(),运行结果如下图所示.
    %prun的使用.jpg
    使用命令%run -p -s cumulative 2.py也能得到上述命令行的执行结果,但不需退出IPython。
    有时通过上述基本性能分析所得到的信息不足以说明函数的执行时间,或函数复杂到难以理解,对于上述情况可使用line_profiler库来实现性能的分析。其中魔术命令%lprun可对一个或多个函数进行逐行的性能分析,若想使用魔术命令%lprun,需要进行相关操作,具体如下所示:

    1.安装line_profiler库

    在控制台(Win+R,并输入cmd)使用命令conda install line_profiler安装line_profiler库。

    2.修改配置文件

    由于line_profiler属于扩展文件,因此需要在配置文件(ipython_config.py)中添加下列内容,具体示例如下所示:

    c.TerminalIPythonApp.extensions = ['line_profiler']
    

    若系统中没有配置文件则使用命令ipython profile create+文件名称”创建,若没有指定文件名称则默认创建名为ipython_config.py的配置文件。

    3.检测是否配置成功

    输入%lprun命令,如下图所示。

    检测%lprun命令.jpg
    图中显示结果证明%lprun命令已可正常使用,接下来使用%lprun命令执行上述代码中run_experiment()函数,如下图所示。
    %lprun命令的使用.jpg
    从图中可看出上述代码中run_experiment()函数每一行代码执行的时间,非常清晰明了,方便分析函数的每行语句的性能。图是只分析了run_experiment()这一个函数,其实%lprun命令还可分析多个函数,其通用语法示例如下所示:
    %lprun -f func1 -f func2 statement_to_profile
    

    在分析程序性能时,可先使用%prun命令作宏观性能分析,然后有针对性的使用%lprun命令作微观性能分析,最终得出让人更加信服的性能分析结果。

    注意:在使用%lprun时,由于%lprun是将函数中每一行代码都进行分析,整体开销都会偏大,因此需要显示指明待测试的函数名,否则会造成开销大、性能分析结果不被人信服的影响。

    相关文章

      网友评论

          本文标题:IPython中的开发工具(二)

          本文链接:https://www.haomeiwen.com/subject/sszlbftx.html