Sage中的剖析¶
本页列出了Sage中可用于测量和分析代码性能的几种方法。有关分析的更多常规信息,请参阅 :wikipedia:`Profiling_(computer_programming)` .
目录
要多长时间?%时间和%timeit¶
两个伊普顿魔术师 %time
和 %timeit
测量运行命令所需的时间:
sage: %time p=random_prime(2**300)
CPU times: user 152 ms, sys: 0 ns, total: 152 ms
Wall time: 150 ms
sage: %timeit p=random_prime(2**300)
10 loops, best of 3: 62.2 ms per loop
注意,同时 %time
只运行一次命令, %timeit
尝试在多次运行中返回更有意义的值。
有关详细信息,请参阅 %timeit?
or this page .
请注意,Sage提供了一个 timeit
函数也运行在Sage笔记本中。
Python级函数调用:%prun¶
用 %prun
,您可以获得计算中涉及的所有Python函数的列表,以及每个函数所花费的时间:
sage: %prun _=random_prime(2**500)
468 function calls in 0.439 seconds
Ordered by: internal time
ncalls tottime percall cumtime percall filename:lineno(function)
32 0.438 0.014 0.438 0.014 {method 'is_prime' of 'sage.rings.integer.Integer' objects}
32 0.001 0.000 0.439 0.014 arith.py:407(is_prime)
32 0.000 0.000 0.001 0.000 random.py:175(randrange)
32 0.000 0.000 0.000 0.000 random.py:244(_randbelow)
...
最耗时的函数应该出现在顶部。不同列的描述是 available here .
注解
您可能需要对该列表进行不同的排序,例如:使用 %prun -s cumulative
减少累积时间。
或者,您可以将此数据“保存”到 Stats
进一步检查的对象:
sage: %prun -r random_prime(2**500)
sage: stats_object = _
sage: stats_object.total_calls
2547
有关详细信息,请参阅 %prun?
or this page .
可视化统计数据: 您可以使用 RunSnake 以及Sage的功能 runsnake()
::
sage: runsnake('random_prime(2**500)')
Python级别逐行分析:%lprun¶
用 line_profiler 及其 %lprun
神奇的是,你可以找出一个(或多个)函数的哪一行最耗时。语法如下:
%lprun -f function1 -f function2 code_to_run
这将显示 function1
和 function2
什么时候? code_to_run
执行日期:
sage: %lprun -f random_prime random_prime(2**500)
Line # Hits Time Per Hit % Time Line Contents
==============================================================
1193 def random_prime(n, proof=None, lbound=2):
... ...
1251 # since we don't want current_randstate to get
1252 # pulled when you say "from sage.arith.all import *".
1253 1 11 11.0 0.0 from sage.misc.randstate import current_randstate
1254 1 7 7.0 0.0 from sage.structure.proof.proof import get_flag
1255 1 6 6.0 0.0 proof = get_flag(proof, "arithmetic")
1256 1 17 17.0 0.0 n = ZZ(n)
...
为了安装 line_profiler
必须首先运行以下命令:
[user@localhost ~] sage -pip install "line_profiler"
C级函数调用:%crun¶
用 %crun
,您可以获得计算中涉及的所有C函数的列表,以及每个函数所花费的时间。你需要 the Google performance analysis tools 安装在您的系统上:
sage: %crun p=random_prime(2**500)
PROFILE: interrupts/evictions/bytes = 45/0/18344
Total: 45 samples
0 0.0% 0.0% 35 77.8% PyEval_EvalCode
0 0.0% 0.0% 35 77.8% PyEval_EvalCodeEx
0 0.0% 0.0% 35 77.8% PyEval_EvalFrameEx
0 0.0% 0.0% 35 77.8% PyObject_Call
0 0.0% 0.0% 35 77.8% PyRun_StringFlags
0 0.0% 0.0% 35 77.8% __Pyx_PyObject_Call.constprop.73
...
有关更多信息 %crun
见 sage.misc.gperftools
.
C级逐行分析:perf(仅限Linux)¶
如果您的代码是用C或Cython编写的,您可以一行一行地找出使用成本最高的代码 perf (包含在Ubuntu包中 linux-tools
)
使用它最简单的方法是在Sage中运行一些(非常长的)计算,并在控制台中键入
[user@localhost ~] sudo perf top
选择您感兴趣的条目,然后按 Enter
. 这个 annotate
命令将显示:
CPU指令
源代码
相关时间
│ * cdef unsigned long word = (<unsigned long>1) << (v & self.radix_mod_mask)
│ * return (self.edges[place] & word) >> (v & self.radix_mod_mask) # <<<<<<<<<<<<<<
│ *
│ * cpdef bint has_arc(self, int u, int v) except -1:
│ */
│ __pyx_r = (((__pyx_v_self->edges[__pyx_v_place]) & __pyx_v_word) >> (__pyx_v_v & __pyx_v_self->radix_mod_mask));
10.88 │ movslq %esi,%rsi
6.52 │ and (%rdi,%rsi,8),%rax
12.84 │ shr %cl,%rax
注解
按
s
切换到源代码按
H
循环浏览最热门的指令按
h
寻求帮助
或者,如果你没有 sudo
权限,可以将特定进程的统计信息记录到文件中 perf.data
从它的PID。然后,使用 perf report
:
[user@localhost ~] perf record -p PID
[user@localhost ~] perf report --vmlinux vmlinux