Erlang/OTP - 计时应用

Posted

技术标签:

【中文标题】Erlang/OTP - 计时应用【英文标题】:Erlang/OTP - Timing Applications 【发布时间】:2011-05-18 19:27:42 【问题描述】:

我有兴趣对我的程序的不同部分进行基准测试以提高速度。我尝试过使用info(statistics)erlang:now()

我需要知道精确到微秒的平均速度是多少。我不知道为什么我写的脚本有问题。

它应该能够从任何地方开始并在任何地方结束。当我尝试在可能并行运行多达四次的进程上启动它时遇到了问题。

有没有人已经解决了这个问题?

编辑:

如果有人可以提供脚本来执行此操作,愿意提供赏金。它需要通过多个进程产生。我不能接受像计时器这样的功能......至少在我见过的实现中。 IT 只遍历一个过程,即便如此,对完整程序的完整测试也需要进行一些重大编辑。希望我说得够清楚。

【问题讨论】:

有几个奇怪的地方:这是一个生产系统吗? eprof尤其是 fprof 在运行时会导致性能下降。两者都可以遵循新产生的过程。但是,您可能想要测量其他东西,例如网络往返等等!最简单的方法可能是在要测量的函数周围注入一个timer:tc 调用。或者,将erlang:now() 发送到另一个可以进行测量工作的流程。 您的 eprof 脚本(或演练)位于页面下方 :) 【参考方案1】:

以下是 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 对生产系统或运行时间过长的功能来说可能是相当大的负载。尤其是在生产系统上。

【讨论】:

干得好,试了试,看起来不错。 一个问题:为什么某些进程在我的编中说 0 调用?我知道必须调用它才能有一些其他的乐趣,例如调用 lists:flatten。这很明显吗?或者对我的前卫来说更深奥一点。 我不能说没有代码——我不记得在我自己的代码中看到过。【参考方案2】:

您可以使用eprof or fprof。

【讨论】:

【参考方案3】:

执行此操作的正常方法是使用 timer:tc。 Here 是一个很好的解释。

【讨论】:

我需要它来跨进程运行,而不仅仅是测试一个。【参考方案4】:

我可以向你推荐这个工具:https://github.com/virtan/eep

您将得到类似https://raw.github.com/virtan/eep/master/doc/sshot1.png 的结果。

分析正在运行的系统上的所有进程的分步说明:

在目标系统上:

1> eep:start_file_tracing("file_name"), timer:sleep(20000), eep:stop_tracing().
$ scp -C $PWD/file_name.trace desktop:

在桌面上:

1> eep:convert_tracing("file_name").
$ kcachegrind callgrind.out.file_name

【讨论】:

以上是关于Erlang/OTP - 计时应用的主要内容,如果未能解决你的问题,请参考以下文章

运行守护程序的 Erlang/OTP 应用程序的行业标准?

使用 OTP/Erlang 作为 Web 应用程序基于组件的架构的一部分

初学者的 Erlang/OTP 行为

Erlang OTP 应用程序设计

您如何设计基于Erlang / OTP的分布式容错多核系统的架构?

Erlang/OTP持续部署简介