介绍
通常我们可以用python profiler去分析应用程序中哪个模块被多次调用和那个程序部分运行的速度较为缓慢,但是并不能够准确给出我们应用程序在运行中在内存中占用的大小。
比如说在金融数据中会操作大量的实际数据驻存到内存中,并对数据空间大小和性能能够有更好的优化,就需要考虑内存的测量,保证不会造成程序在运行中过载的压力引发程序上的异常。
有些情况下在python中定义类class 会开辟更多的内存,尤其是创建更多的实例数据就会内存的大量占用。有些情况下需要在类中定义__slots__来封装属性,但是这样会破坏类中内置的__dict__.
对于大量的数据运算和分析,这时候对内存的分配就需要额外的关注和分析,能够得到程序在运行时的内存方面的统计能够更好的提升程序的性能。
Valgrind
Valgrind 能够动态分析程序性能的工具,能够自动测量内存管理和线程中的Bug,给出更详细的测量工具。
- 内存错误探测
- 双线程错误探测
- 缓存和分支结构分析器
- 堆分析器
- 程序调用结构缓存和分支结构分析器
简单介绍一下Valgrind,更详细的内容可以参考官网.
示例
如何用来分析python方面程序的性能呢?
比如在做大量数据运算和分析上,用pytables读取大量数据,pytables的数据存贮是采用HDF5存贮结构进行数据存贮,HDF5是支持大量数据读取和性能上有一定的提升相对于数据库系统,但是并不能是一个有效的数据库系统,这里不要误解,HDF5是对某些数据的高速读取和录入上有很好的性能,不是一个关系型数据库也不是NoSQL数据库。HDF5玩起来非常的不容易。这里采用了两个库numpy和 pytables,这里在HDF5创建50个array dataset,每个array的长度为10000000。python的代码:
import tables
import numpy as np
h5file = tables.openFile('test4.h5', mode='w', title="Test Array")
array_len = 10000000
arrays = np.arange(50)
for x in arrays:
x_a = np.zeros(array_len, dtype=float)
h5file.createArray(h5file.root, "test" + str(x), x_a)
h5file.close()
如何分析性能
- massif
massif 能够检测系统中的内存占用情况。我们将上述的代码保持成test.py
valgrind –tool=massif python test.py
然后我们就会生成一个massif.out.???中的内容,然后我们可以用 ms_print 命令。
massif.out.12076 > profile.txt
MB
558.5^ #. .. .
| #: :: :
| #: :: :
| @::#:: ::: :: @::
| @::#:: ::: :: @::
| ,. @.:#::. ::: ::.@::
| @: @::#::: ::: :::@::
| @: @::#::: ::: :::@::
| , @: @::#::: ::: :::@::
| @ @: @::#::: ::: :::@::
| @ @: @::#::: ::: :::@::
| @@ @: @::#::: ::: :::@::
| @@ @: @::#::: ::: :::@::
| @@ @: @::#::: ::: :::@::
| ::::@@ @: @::#::: ::: :::@::
| ::::@@ @: @::#::: ::: :::@::
| ,::::@@ @: @::#::: ::: :::@::
| @::::@@ @: @::#::: ::: :::@::
| @::::@@ @: @::#::: ::: :::@::
| ...,....@::::@@ @: @::#::: ::: :::@:.
0 +----------------------------------------------------------------------->Gi
0 7.121
程序在启动中大概占用了500m的内存容量,通过图表我们可以直观的看到内存的数据增长,并且能够有效的理解内存上的分配数据。
后续我们就可以通过代码上的优化调整内存中的数据和性能。