In [27]:
%%writefile slow_app.py
import sys
import time
def mock_download():
for i in range(5):
time.sleep(1)
def mock_database():
for i in range(20):
time.sleep(0.1)
def mock_calcate():
for i in range(100000000):
pass
def main():
mock_download()
mock_database()
mock_calcate()
if __name__ == "__main__":
sys.exit(main())
In [13]:
!time -p python slow_app.py
上面可以初步看到程序本身执行时间很短,大部分时间在等待写什么. 只能看到一个大概,不能定位到具体代码.
In [1]:
%%writefile timer.py
import time
class Timer(object):
def __init__(self, verbose=False):
self.verbose = verbose
def __enter__(self):
self.start = time.time()
return self
def __exit__(self, *args):
self.end = time.time()
self.secs = self.end - self.start
self.msecs = self.secs * 1000 # millisecs
if self.verbose:
print('elapsed time: %f ms', self.msecs)
In [2]:
from timer import Timer
with Timer() as t:
for i in range(1000000):
pass
print('elasped time %s s',t.secs)
可以将耗时写到日志里,这样在写代码的时候对关键的逻辑处(数据库、网络等)进行如上改写,然后通过分析日志排查性能问题. 当然也可以扩展一下将每次性能数据写入数据库分析.
line_profiler可以分析每一行代码的执行耗时信息.
line_profiler,使用pip install line_profiler进行安装. 安装成功后可以看到叫做kernprof的可执行程序.@profile装饰器.(不需要显示import任何模块,kernprof会自动注入的)
In [28]:
%%writefile slow_app_for_profiler.py
import sys
import time
@profile
def mock_download():
for i in range(5):
time.sleep(1)
@profile
def mock_database():
for i in range(20):
time.sleep(0.1)
@profile
def main():
mock_download()
mock_database()
if __name__ == "__main__":
sys.exit(main())
In [29]:
!pip install line_profiler
In [30]:
!kernprof -l -v slow_app_for_profiler.py
-l选项告诉kernprof注入@profile到脚本里. -v告诉kernprof显示执行结果到控制台.
Line #:行号.Hits: 这行代码运行次数.Time: 这一行总耗时Per Hit: 本行代码执行一次耗时.% Time:本行耗时占总耗时(函数耗时)百分比.Line Contents: 代码从结果可以很清楚的看到每一行的耗时, 这个对于一般的脚本很方便, 但是对于django项目怎么办呢:
django-devserver: 这个适合在开发环境发现一些性能问题,但是很多问题在线上才能发现. http://djangotricks.blogspot.com/2015/01/performance-bottlenecks-in-django-views.htmldjango-debug-toolbar:yet-another-django-profiler大概瞄了一眼django-devserver使用的是LineProfiler,我们可以在代码层面加入LineProfiler.
memory_profiler分析每一行内存消耗.
In [26]:
!pip install memory_profiler psutil
In [31]:
!python -m memory_profiler slow_app_for_profiler.py