python3.6使用line-profiler踩坑记录

0.背景

       前两天在服务器上使用top指令后看到load average到达了11.96, 12.78, 13.58,对于8核的机器来说这个load有些偏高了,之前load一般保持在5左右。于是,在top中按C查看进程详情,发现有一个脚本开了多进程,并且每个进程的CPU使用率都极高,初步断定就是这个脚本导致了服务器load飙升。随后检查了该脚本的代码,肉眼未能发现不妥之处,于是就需要用到本文要介绍的神器,line-profiler。

1.安装

       查看PyPI后,直接pip3 install line_profiler,果不其然,每次接触新事物的第一步都是报错,如下:

    #include "Python.h"
                        ^
    compilation terminated.
    error: command 'gcc' failed with exit status 1

百度报错信息,有人说需要安装cython,但检查发现服务器上已经安装了gcc,所以估计安装cython并不能解决问题。装好cython后再次安装line-profiler,依旧报同样的错,果然和猜测的一样,cython解决不了我们的问题,继续百度。
       仔细查看报错信息,发现问题出在#include “Python.h”,那么安装一个对应的devel环境或可解决。

yum install python-devel

不对,这好像是python2的,我用的是python3.6,NG…

yum install python36-devel

除了python-devel之外,还有一些可能用到的包,一并安装

yum install -y libffi-devel python36-devel openssl-devel

安装完依赖后继续尝试安装line-profiler,Duang~依旧报错T.T…之后不知道在哪里看到的,把python36-devel换成了python36u-devel后,才成功安装了line_profiler。前后折腾了大概两个小时,终于可以使用line_profiler了。

2.使用

       line_profiler的使用非常简单,在需要测试的函数前加上@profile装饰器,并且不需要import任何包,如下面的demo所示:

@profile
def set_md5(char_val):
    """
    md5加密
    :param char_val: 需要加密的字符
    :return:
    """
    if not isinstance(char_val, bytes):
        char_val = char_val.encode("utf-8")
    m = hashlib.md5()
    m.update(char_val)
    return m.hexdigest()

把整段代码放在test.py文件中,在代码所在位置kernprof -l -v test.py等待执行完毕。执行完毕后屏幕上看到如下输出:

Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
     6                                           @profile
     7                                           def set_md5(char_val):
     8                                               """
     9                                               md5加密
    10                                               :param char_val: 需要加密的字符
    11                                               :return:
    12                                               """
    13         1          7.0      7.0     13.0      if not isinstance(char_val, bytes):
    14         1          2.0      2.0      3.7          char_val = char_val.encode("utf-8")
    15         1          8.0      8.0     14.8      m = hashlib.md5()
    16         1         16.0     16.0     29.6      m.update(char_val)
    17         1         21.0     21.0     38.9      return m.hexdigest()

输出结果中,Hits和Time比较高的那几行代码,就是优化空间最大的地方,是最需要关注的代码。

3.说完了

       在分析python性能这块,line_profiler主要关注的是执行时间,除此之外,还有分析内存性能的memory_profiler,和能够分析内存泄漏的objgraph,都是很实用很有意思的工具,未来找机会试用一下。看完本文,相信你以后不会再傻傻的使用time工具来计时测性能啦。

发布了24 篇原创文章 · 获赞 39 · 访问量 12万+

猜你喜欢

转载自blog.csdn.net/shayuchaor/article/details/90749305