叨叨 Python 性能优化工具

浏览: 2663

虽然Python是一个”慢慢的“语言,但是不代表我们对性能没有任何的追求,在程序运行过程中,如果发现程序运行时间太长或者内存占用过大,免不了需要对程序的执行过程进行一些监测,找到有问题的地方,进行优化。今天来分享一些平时用到的Python性能分析工具

memory_profiler

memory_profiler是监控python进程的神器,只需要在函数加一个装饰器就可以输出每行代码的内存使用情况

安装:

pip install memory_profiler

使用:

    import time

    @profile
    def my_func():
    a = [1] * (10 ** 6)
    b = [2] * (2 * 10 ** 7)
    time.sleep(10)
    del b
    del a
    print "+++++++++"

    if __name__ == '__main__':
    my_func()

    输出:

      $ python -m memory_profiler del3.py
      +++++++++
      Filename: del3.py

      Line # Mem usage Increment Line Contents
      ================================================
      10.293 MiB 0.000 MiB @profile
      def my_func():
      17.934 MiB 7.641 MiB a = [1] * (10 ** 6)
      170.523 MiB 152.590 MiB b = [2] * (2 * 10 ** 7)
      170.527 MiB 0.004 MiB time.sleep(10)
      17.938 MiB -152.590 MiB del b
      10.305 MiB -7.633 MiB del a
      10.309 MiB 0.004 MiB print "+++++++++"

      内建函数 timeit

        import timeit
        import time

        def my_func():
        time.sleep(1)
        return sum([1,2,3])

        result = timeit.timeit(my_func, number=5)
        print(result)

        Jupyter Notebook Magic 命令

        在Jupyter Notebook中,可以通过%%timeit魔法命令测试cell中代码的运行时间

          %%timeit

          import time
          def my_func():
          time.sleep(1)
          return sum([1,2,3])

          result = timeit.timeit(my_func, number=5)
          print(result)

          计时装饰器

          Python 中的装饰器可以在其他函数不需要改动任何代码的情况下增加额外功能,经常用在,插入日志、性能测试、权限校验等场景中。我们可以将计时功能封装成一个装饰器,方便复用。

            %%timeit

            import time
            def my_func():
            time.sleep(1)
            return sum([1,2,3])

            result = timeit.timeit(my_func, number=5)
            print(result)

            使用:

              from functools import wraps
              import time

              def timeit(func):
              @wraps(func)
              def deco():
              start = time.time()
              res = func()
              end = time.time()
              delta = end - start
              print("Wall time ", delta)
              return res
              return deco

              输出:

                Wall time: 3

                line_profiler

                如果我们除了想知道代码整体的运行时间之外,还要精确分析每行代码的运行时间,那python的 line_profiler 模块就可以帮到你啦!line_profiler 可以用来测试函数每行代码的响应时间等情况。为了使用方便,可以将line_profiler 相关函数封装在装饰器中进行使用,这样在接口请求时,则会执行此装饰器并打印出结果。

                安装:

                  pip install line_profiler

                  使用:

                    from flask import Flask, jsonify
                    import time
                    from functools import wraps
                    from line_profiler import LineProfiler

                    # 查询接口中每行代码执行的时间
                    def func_line_time(f):
                    @wraps(f)
                    def decorator(*args, **kwargs):
                    func_return = f(*args, **kwargs)
                    lp = LineProfiler()
                    lp_wrap = lp(f)
                    lp_wrap(*args, **kwargs)
                    lp.print_stats()
                    return func_return
                    return decorator

                    app = Flask(__name__)

                    @app.route('/line_test')
                    @func_line_time
                    def line_test():
                    for item in range(5):
                    time.sleep(1)
                    for item in xrange(5):
                    time.sleep(0.5)
                    return jsonify({'code':200})


                    if __name__=='__main__':
                    app.run()

                    输出:

                      from flask import Flask, jsonify
                      import time
                      from functools import wraps
                      from line_profiler import LineProfiler

                      # 查询接口中每行代码执行的时间
                      def func_line_time(f):
                      @wraps(f)
                      def decorator(*args, **kwargs):
                      func_return = f(*args, **kwargs)
                      lp = LineProfiler()
                      lp_wrap = lp(f)
                      lp_wrap(*args, **kwargs)
                      lp.print_stats()
                      return func_return
                      return decorator

                      app = Flask(__name__)

                      @app.route('/line_test')
                      @func_line_time
                      def line_test():
                      for item in range(5):
                      time.sleep(1)
                      for item in xrange(5):
                      time.sleep(0.5)
                      return jsonify({'code':200})


                      if __name__=='__main__':
                      app.run()

                      pyheat

                      相较于上面的代码运行时间测试工具,pyheat 通过matplotlib 的绘制热力图来展现代码的运行时间,显得更为直观

                      安装:

                        pip install py-heat

                        使用方法:

                          pyheat <path_to_python_file> --out image_file.png

                          heartrate

                          heartrate 也是一个可视化的监测工具,可以像监测心率一样追踪程序运行,通过web页面可视化Python程序的执行过程。

                          img

                          左侧数字表示每行代码被触发的次数。长方框表示最近被触发的代码行——方框越长表示触发次数越多,颜色越浅表示最近被触发次数越多。该工具记录的是每行代码执行的次数,

                          而不是具体执行时间,在性能调试的时候有些鸡肋

                          安装:

                            pip install --user heartrate

                            使用:

                              import heartrate
                              from heartrate import trace, files

                              heartrate.trace(browser=True)
                              trace(files=files.path_contains('my_app', 'my_library'))

                              关注公众号,手把手带你通俗易懂学习自然语言处理!

                              扫码下图关注我们不会让你失望!

                              image.png

                              推荐 0
                              本文由 ID王大伟 创作,采用 知识共享署名-相同方式共享 3.0 中国大陆许可协议 进行许可。
                              转载、引用前需联系作者,并署名作者且注明文章出处。
                              本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责。本站是一个个人学习交流的平台,并不用于任何商业目的,如果有任何问题,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。

                              0 个评论

                              要回复文章请先登录注册