python的性能优化方案
python的GIL,多线程,多进程
- GIL: Global Interpreter Lock(全局解释器锁),每个CPU在同一时间之内只能执行一个线程,因为单核CPU的多线程其实都只是并发不是并行。
- 单CPU中进程只能是并发,多CPU进程可以并行
- 单CPU单核中线程只能并发,单CPU多核中线程可以并行
- 并行: 多事件在同一时刻发生
- 并发: 多事件在同一时间间隔内发生
- 每个线程的执行方式: 获取GIL --> 执行代码 --> 释放GIL,在一个python进程里面,只有一个GIL,如果线程拿不到这个GIL就无法运行。
- GIL的释放逻辑: 1. python2:当前线程遇见IO操作或者ticks计数达到100。2. python3:改用计时器,执行时间达到阀值释放GIL
使用Ubuntu Apache AB进行压力测试
sudo apt-get install apache2-utils
ab -n 100 -c 10 http://localhost/demo/
-n 代表的是总的请求数,-c代表一次并发里面的请求数
具体项目优化方案:
-
read DB:读取数据库的时候,使用cache
-
代码逻辑:尽量避免在for循环里面使用query
-
给logger加上判断,当debug模式为False的时候,很多不必要的地方不需要写log
-
gunicorn:使用gevent启用worker,将worker的数量变成三个,核数+1,将gevent放在requirement中。Worker个数,Worker类型,TImeout时间
-
Nginx: 修改配置文件,timeout设置为600/300s
在最外面加上:worker_rlimit_nofile 65535;
在http块内加上:
fastcgi_send_timeout 600; fastcgi_read_timeout 600;
在server块的location里面加上:
proxy_connect_timeout 600s; proxy_read_timeout 600s; proxy_send_timeout 600s;
-
NAS:挂载参数上需要增加一个noresvport参数来规避以后例行维护可能造成的NAS服务中断https://c.tb.cn/a.cAQOl
-
使用python的一些计算运行时间的工具来优化代码,CProfile、line_profiler、TimeDelta
-
对python本身的一些优化 pypy/cpython
使用line_profiler工具分析python代码性能以及性能调优
line_profiler
是一个对函数进行逐行分析的模块,kernprof
是一个可以运行line_profiler
或者python标准库cProfile
的一个很方便的脚本工具。
安装:
$ pip install line_profiler
遇到错误提示没有Cpython,安装一下:
pip install Cpython
继续报错:command 'x86_64-linux-gnu-gcc' failed with exit status 1
解决方案:https://github.com/scrapy/scrapy/issues/2115
里面的sudo apt install python3.6-dev
解决了问题
首先使用kernprof脚本运行来开始我们的性能优化工作:
kernprof -l run.py
上面的操作会创建一个LineProfiler
的实例并且会把它插入到命名空间里面。然后它能以装饰器的方式来使用,所以我们只需要把我们需要分析的函数上面套上这个装饰器:
@profile
def func_need_profile(*args, **kwargs):
...
这里直接加上装饰器,不需要在代码里面额外import任何东西。
kernprof
会把分析的结果放在script_to_profile.py.lprof
这个二进制文件里面,然后我们可以去看这个分析结果:
python -m line_profiler run.py.lprof