python性能调优的一次记录
admin
2023-07-31 00:38:18
0

最近在grahite上看到响应时间变得很长,虽说之前没有特意去优化性能,但是感觉也不应该这么差才对。

QQ20150406 1

我们的服务器框架用的就是我之前开源的 maple,每个命令字都对应一个入口函数,如下:

12345678910 @app.route(2)def login(request):    logger.error(\”login: %s\”, request.gw_box)    uid = request.box.get_json()[\”uid\”]    request.login_client(uid)    time.sleep(1)    request.write_to_client(dict(        ret=0,        body=\”login %s\” % uid    ))

 

所以只要找到一种方法分析这个函数对应的内部调用情况就可以了。

很方便的,python内置了cProfile类来完成我们想要的功能,我给封装成为一个装饰器,用起来更方便一些,当然在django和flask中也可以直接用。

12345678910 def monitor_profile(func):    import cProfile    import functools    @functools.wraps(func)    def func_wrapper(*args, **kwargs):        def tmpfunc():            return func(*args, **kwargs)        # 直接用run是不行的        cProfile.runctx(\”tmpfunc()\”, globals(), locals(), \”%s.stat\” % func.__name__)    return func_wrapper

 

执行到对应的函数后,就会将统计写到函数名对应的stat文件中,比如 login.stat。

相应的,我也封装了一个分析工具:

12345678910111213141516171819202122232425 import sysimport argparseimport pstats def build_parser():    parser = argparse.ArgumentParser()    parser.add_argument(\’-f\’, \’–file\’, help=\’stat filename\’, action=\’store\’, required=True)    parser.add_argument(\’-s\’, \’–sort\’, help=\’sort type: cumulative, time\’, action=\’append\’)    parser.add_argument(\’-p\’, \’–percent\’, help=\’sort type\’, action=\’store\’, default=0.5, type=float)    parser.add_argument(\’-d\’, \’–dir\’, help=\’show directory\’, action=\’store_true\’)    return parser def main():    args = build_parser().parse_args()    p = pstats.Stats(args.file)     sort_keys = args.sort or (\’cumulative\’, \’time\’)     if not args.dir:        p = p.strip_dirs()     p.sort_stats(*sort_keys).print_stats(args.percent) if __name__ == \’__main__\’:    main()

 

用起来非常简单,执行一下:

1 python stat.py f login.stat p0.1

 

输出结果如下:

12345678910111213141516171819 Mon Apr  6 11:16:02 2015    login.stat          442 function calls (439 primitive calls) in 1.002 seconds    Ordered by: cumulative time, internal time   List reduced from 107 to 11 due to restriction    ncalls  tottime  percall  cumtime  percall filename:lineno(function)        1    0.000    0.000    1.002    1.002 :1()        1    0.000    0.000    1.002    1.002 worker.py:40(tmpfunc)        1    0.000    0.000    1.002    1.002 worker.py:46(login)        1    1.000    1.000    1.000    1.000 {time.sleep}        1    0.000    0.000    0.001    0.001 request.py:73(write_to_client)        1    0.000    0.000    0.001    0.001 __init__.py:1176(error)        1    0.000    0.000    0.001    0.001 __init__.py:1260(_log)        3    0.000    0.000    0.000    0.000 box.py:41(__init__)        1    0.000    0.000    0.000    0.000 request.py:146(login_client)        1    0.000    0.000    0.000    0.000 __init__.py:1281(handle)        1    0.000    0.000    0.000    0.000 __init__.py:1313(callHandlers)

 

可以明显看到时间消耗在 time.sleep 上。

好了,上面只是一个简单的示例,接下来看今天解决的问题的真实情况。

下面两张图分别是牌桌内有2人和7人的情况下的调用图。

2人:

QQ20150406 3

7人:

QQ20150406 2

 

异常的部分均使用颜色加亮了,可以看出几个端倪:

  1. 随着人数变多,有些部分的请求翻了几倍
  2. 读取数据库和redis的调用量太大

既然知道了是与存储通信的问题,那么接下来就来看看是哪些地方调用了 get_db_user,get_user_from_db。

cProfile 提供了一个方法:

12 #如果想知道有哪些函数调用了bar,可使用p.print_callers(0.5, \”bar\”)

 

所以通过这种方法拿到:

4EF1E801 22DE 45B1 BC10 9CF9154FB56B

CBF7C01C C2D2 4164 A5C7 673B38B11EB4

 

所以接下来就去看下上面的代码中这些数据库调用是否是必要就可以了。

基本就是这样了。

另外之前也出现过python内存泄漏的定位,可惜没有写下来文档,只记得是用 objgraph,不过用起来也比较简单,等下次遇到再说吧。


相关内容

热门资讯

500 行 Python 代码... 语法分析器描述了一个句子的语法结构,用来帮助其他的应用进行推理。自然语言引入了很多意外的歧义,以我们...
定时清理删除C:\Progra... C:\Program Files (x86)下面很多scoped_dir开头的文件夹 写个批处理 定...
65536是2的几次方 计算2... 65536是2的16次方:65536=2⁶ 65536是256的2次方:65536=256 6553...
Mobi、epub格式电子书如... 在wps里全局设置里有一个文件关联,打开,勾选电子书文件选项就可以了。
scoped_dir32_70... 一台虚拟机C盘总是莫名奇妙的空间用完,导致很多软件没法再运行。经过仔细检查发现是C:\Program...
小程序支付时提示:appid和... [Q]小程序支付时提示:appid和mch_id不匹配 [A]小程序和微信支付没有进行关联,访问“小...
pycparser 是一个用... `pycparser` 是一个用 Python 编写的 C 语言解析器。它可以用来解析 C 代码并构...
微信小程序使用slider实现... 众所周知哈,微信小程序里面的音频播放是没有进度条的,但最近有个项目呢,客户要求音频要有进度条控制,所...
python查找阿姆斯特朗数 题目解释 如果一个n位正整数等于其各位数字的n次方之和,则称该数为阿姆斯特朗数。 例如1^3 + 5...
Apache Doris 2.... 亲爱的社区小伙伴们,我们很高兴地向大家宣布,Apache Doris 2.0.0 版本已于...