在IPython中,既可以用timeit分析一小段代码的性能,也可以在运行脚本的时候对整个脚本进行分析。对这两种性能分析方式,我们都将予以介绍。
具体步骤
首先,我们要测量一个代码片段的执行时间。
- 测量代码片段的执行时间。
以pylab模式启动IPython。
ipython -pylab
创建一个包含1000个整数的数组,其取值范围在0到1000之间。
In [1]: a = arange(1000)
测量在该数组中查找“任何事情的答案”——42所需要的时间。没错,42是“任何事情的答案”。如果你对此心存疑问,请浏览http://en.wikipedia.org/wiki/42_%28number%29。
In [2]: %timeit searchsorted(a, 42)
100000 loops, best of 3: 7.58 us per loop
- 分析一个脚本的性能。
我们将分析一个小脚本的性能。该脚本对一系列不同大小的、包含随机数的矩阵求逆。NumPy数组的.I
属性(注意是大写的I)表示数组的逆矩阵。
import numpy
def invert(n):
a = numpy.matrix(numpy.random.
rand(n, n))
return a.I
sizes = 2 ** numpy.arange(0, 12)
for n in sizes:
invert(n)
可以用如下方式,对该脚本的运行时间进行测量。
In [1]: %run -t invert_matrix.py
IPython CPU timings (estimated):
User : 6.08 s.
System : 0.52 s.
Wall time: 19.26 s.
可以使用p
选项对脚本进行性能分析。
In [2]: %run -p invert_matrix.py
852 function calls in 6.597 CPU seconds
Ordered by: internal time
ncalls tottime percall cumtime percall filename:lineno(function)
12 3.228 0.269 3.228 0.2 {numpy.linalg.lapack_lite.dgesv}
24 2.967 0.124 2.967 0.124 {numpy.core.multiarray._fastCopyAndTranspose}
12 0.156 0.013 0.156 0.013 {method 'rand' of 'mtrand.RandomState' objects}
12 0.087 0.007 0.087 0.007 {method 'copy' of 'numpy.ndarray' objects}
12 0.069 0.006 0.069 0.006 {method 'astype' of 'numpy.ndarray' objects}
12 0.025 0.002 6.304 0.525 linalg.py:404(inv)
12 0.024 0.002 6.328 0.527 defmatrix.py:808(getI)
1 0.017 0.017 6.596 6.596 invert_matrix.py:1()
24 0.014 0.001 0.014 0.001 {numpy.core.multiarray.zeros}
12 0.009 0.001 6.580 0.548 invert_matrix.py:3(invert)
12 0.000 0.000 6.264 0.522 linalg.py:244(solve)
12 0.000 0.000 0.014 0.001 numeric.py:1875(identity)
1 0.000 0.000 6.597 6.597 {execfile}
36 0.000 0.000 0.000 0.000 defmatrix.py:279(__array_finalize__)
12 0.000 0.000 2.967 0.247 linalg.py:139(_fastCopyAndTranspose)
24 0.000 0.000 0.087 0.004 defmatrix.py:233(__new__)
12 0.000 0.000 0.000 0.000 linalg.py:99(_commonType)
24 0.000 0.000 0.000 0.000 {method '__array_prepare__' of 'numpy.ndarray' objects}
36 0.000 0.000 0.000 0.000 linalg.py:66(_makearray)
36 0.000 0.000 0.000 0.000 {numpy.core.multiarray.array}
12 0.000 0.000 0.000 0.000 {method 'view' of 'numpy.ndarray' objects}
12 0.000 0.000 0.000 0.000 linalg.py:127(_to_native_byte_order)
1 0.000 0.000 6.597 6.597 interactiveshell.py:2270(safe_execfile)
攻略小结
我们用性能分析工具对上述NumPy脚本的运行过程进行了分析。下表对分析工具的输出项目进行了总结。
列 | 描述 |
---|---|
ncalls |
调用次数 |
tottime |
总的函数执行时间 |
percall |
单次调用的执行时间,即tottime/ncalls |
cumtime |
函数的累计执行时间,包括该函数本身的执行时间、在该函数内部调用其他函数花费的时间和递归调用花费的时间 |