以下是 eprof 的使用方法,这可能是您最简单的解决方案:
首先你需要启动它,就像大多数应用程序一样:
23> eprof:start().
{ok,<0.95.0>}
Eprof 支持两种分析模式。您可以调用它并要求分析某个功能,但我们不能使用它,因为其他进程会搞砸一切。我们需要手动启动它并告诉它何时停止(这就是为什么你不会有一个简单的脚本,顺便说一句)。
24> eprof:start_profiling([self()]).
profiling
这告诉 eprof 分析所有将从 shell 运行和生成的东西。此处将包含新流程。我将运行一些我拥有的任意多处理函数,它会产生大约 4 个进程相互通信几秒钟:
25> trade_calls:main_ab().
Spawned Carl: <0.99.0>
Spawned Jim: <0.101.0>
<0.100.0>
Jim: asking user <0.99.0> for a trade
Carl: <0.101.0> asked for a trade negotiation
Carl: accepting negotiation
Jim: starting negotiation
... <snip> ...
我们现在可以告诉 eprof 在函数运行完成后停止分析。
26> eprof:stop_profiling().
profiling_stopped
我们想要日志。默认情况下,Eprof 会将它们打印到屏幕上。您可以要求它也使用eprof:log(File) 登录到一个文件。然后你可以告诉它分析结果。我们告诉它使用选项total 将所有进程的运行时间折叠到一个表中(有关更多选项,请参见manual):
27> eprof:analyze(total).
FUNCTION CALLS % TIME [uS / CALLS]
-------- ----- --- ---- [----------]
io:o_request/3 46 0.00 0 [ 0.00]
io:columns/0 2 0.00 0 [ 0.00]
io:columns/1 2 0.00 0 [ 0.00]
io:format/1 4 0.00 0 [ 0.00]
io:format/2 46 0.00 0 [ 0.00]
io:request/2 48 0.00 0 [ 0.00]
...
erlang:atom_to_list/1 5 0.00 0 [ 0.00]
io:format/3 46 16.67 1000 [ 21.74]
erl_eval:bindings/1 4 16.67 1000 [ 250.00]
dict:store_bkt_val/3 400 16.67 1000 [ 2.50]
dict:store/3 114 50.00 3000 [ 26.32]
您可以看到大部分时间(50%)都花在了 dict:store/3 中。 16.67% 用于输出结果,另外 16.67% 用于 erl_eval(这就是为什么在 shell 中运行短函数得到的原因——解析它们比运行它们要长)。
然后您可以从那里开始。这就是使用 Erlang 分析运行时间的基础知识。小心处理,eprof 对生产系统或运行时间过长的功能来说可能是相当大的负载。尤其是在生产系统上。