• python 性能分析(时间,空间)之 line_profiler 模块 ,memory_profiler的使用


    line_profiler使用装饰器(@profile)标记需要调试的函数.用kernprof.py脚本运行代码,被选函数每一行花费的cpu时间以及其他信息就会被记录下来。

    安装

    pip3 install Cpython
    pip3 install Cython git+https://github.com/rkern/line_profiler.git
    conda install -y line_profiler memory_profiler

    代码演示

    loopdemo.py 100以内哪两个数相加等于100.
    首先是没有优化过的双层循环的嵌套

    @profile
    def foo():
        task = []
    
        for a in range(0, 101):
            for b in range(0, 101):
                if a + b == 100:
                    task.append((a, b))
        return task
    
    
    @profile
    def run():
        for item in foo():
            pass
    
    
    if __name__ == '__main__':
        run()
    

    运行下面的命令

    kernprof -l -v loopdemo.py

    -l表示逐行分析,-v用于输出。同时会输出一个文件:juliademo.py.lprof,后期可以对.lprof文件进行分析
    输出结果

    Wrote profile results to loopdemo.py.lprof
    Timer unit: 1e-06 s
    
    Total time: 0.009856 s
    File: loopdemo.py
    Function: foo at line 1
    
    Line #      Hits         Time  Per Hit   % Time  Line Contents
    ==============================================================
         1                                           @profile
         2                                           def foo():
         3         1          1.0      1.0      0.0      task = []
         4
         5       102         47.0      0.5      0.5      for a in range(0, 101):
         6     10302       4741.0      0.5     48.1          for b in range(0, 101):
         7     10201       4975.0      0.5     50.5              if a + b == 100:
         8       101         91.0      0.9      0.9                  task.append((a, b))
         9         1          1.0      1.0      0.0      return task
    
    Total time: 0.017778 s
    File: loopdemo.py
    Function: run at line 12
    
    Line #      Hits         Time  Per Hit   % Time  Line Contents
    ==============================================================
        12                                           @profile
        13                                           def run():
        14       102      17747.0    174.0     99.8      for item in foo():
        15       101         31.0      0.3      0.2          pass

    引入kernprof.py会额外的增加是时间,但是为了检测代码每一行发生了什么,这个影响没什么,实际代码运行的时候是不带@profile装饰器的只有需要line_profiler进行逐行分析的时候才需要加。
    总用时Total time: 0.017778 s
    Hits是调用次数。

    %Time 列告诉我们哪行代码占了它所在函数的消耗的时间百分比,可以看出在foo函数中最消耗时间的是判断a+b==100,占用了50.5%的时间。

    然后我对循环部分做下面的优化其他地方不变。

        for a in range(0, 101):
            b = 100 - a
            task.append((a, b))
        return task

    得到下面的结果

    Wrote profile results to loopdemo.py.lprof
    Timer unit: 1e-06 s
    
    Total time: 0.000126 s
    File: loopdemo.py
    Function: foo at line 1
    
    Line #      Hits         Time  Per Hit   % Time  Line Contents
    ==============================================================
         1                                           @profile
         2                                           def foo():
         3         1          1.0      1.0      0.8      task = []
         4
         5       102         33.0      0.3     26.2      for a in range(0, 101):
         6       101         47.0      0.5     37.3          b = 100 - a
         7       101         45.0      0.4     35.7          task.append((a, b))
         8         1          0.0      0.0      0.0      return task
    
    Total time: 0.000282 s
    File: loopdemo.py
    Function: run at line 11
    
    Line #      Hits         Time  Per Hit   % Time  Line Contents
    ==============================================================
        11                                           @profile
        12                                           def run():
        13       102        256.0      2.5     90.8      for item in foo():
        14       101         26.0      0.3      9.2          pass

    可以发现总用时,循环体里代码的调用次数减少了。

    ===================================================================================

    作用:memory_profiler是用来分析每行代码的内存使用情况

    使用方法一:

       1.在函数前添加 @profile

            2.运行方式: python -m memory_profiler memory_profiler_test.py     

      此方法缺点:在调试 和 实际项目运行时 要 增删 @profile 此装饰器

    代码如下:

    #coding:utf8
    
    @profile
    def test1():
        c=0
        for item in xrange(100000):
            c+=1
        print c
    
    if __name__=='__main__':
        test1()

    输出结果:

    rgc@rgc:~/baidu_eye/carrier/test$ python -m memory_profiler memory_profiler_test.py 
    Filename: memory_profiler_test.py
    
    Line #    Mem usage    Increment   Line Contents
    ================================================
      21.492 MiB   21.492 MiB   @profile
                                def test1():
      21.492 MiB    0.000 MiB       c=0
      21.492 MiB    0.000 MiB       for item in xrange(100000):
      21.492 MiB    0.000 MiB           c+=1
      21.492 MiB    0.000 MiB       print c

    名词含义为

      Mem usage: 内存占用情况

      Increment: 执行该行代码后新增的内存

    使用方法二:

      1.先导入:rom memory_profiler import profile

           2.函数前加装饰器:@profile(precision=4,stream=open('memory_profiler.log','w+'))            

       参数含义:precision:精确到小数点后几位 

          stream:此模块分析结果保存到 'memory_profiler.log' 日志文件。如果没有此参数,分析结果会在控制台输出

      运行方式:直接跑此脚本  python memory_profiler_test.py 

      此方法优点:解决第一种方法的缺点,在 不需要 分析时,直接注释掉此行

    #coding:utf8
    from memory_profiler import profile
    
    @profile(precision=4,stream=open('memory_profiler.log','w+'))
    # @profile
    def test1():
        c=0
        for item in xrange(100000):
            c+=1
        print c
    
    if __name__=='__main__':
        test1()

    使用方法三:

      脚本代码和方法二一样,但是 运行方式不同

      mprof run memory_profiler_test.py: 分析结果会保存到一个 .dat格式文件中

      mprof plot   : 把结果以图片到方式显示出来(直接在本目录下运行此命令即可,程序会自动找出.dat文件) (要安装  pip install matplotlib

           mprof clean  : 清空所有 .dat文件

    关注公众号 海量干货等你
  • 相关阅读:
    sublime text 2安装Emment插件
    PHPExcel IE导出乱码问题
    还是PHPExcel问题
    一条SQL语句查询两表中两个字段
    PHPExcel导出插入图片和居中问题
    jqgrid demo
    openstack horizon 学习(1) 总览
    Python学习笔记
    微软2016校园招聘在线笔试 [Recruitment]
    动态树学习(留坑)
  • 原文地址:https://www.cnblogs.com/sowhat1412/p/12734254.html
Copyright © 2020-2023  润新知