- 浏览: 333119 次
- 性别:
- 来自: 北京
最新评论
-
perfect_control:
真的很详细,一些东西很容易被我忽略掉了
使用fprof进行性能分析 -
leeyisoft:
http://www.erlangqa.com/ 怎么变成 “ ...
Erlang问答网站,欢迎各位提出问题,解答问题。 -
simsunny22:
4年之后我才看到 慢慢的干货
Erlang服务器内存耗尽bug跟踪过程 -
爱死我:
...
使用etop查看系统中进程信息 -
宋兵甲:
在跑这个服务的时候,每秒建立一个客户端连接,连续建立10000 ...
自己写一个tcp 通用服务器
Erlang tools lib中包含三个用于性能分析的工具:cprof,eporf和fprof。
cprof 提供函数调用计数,其对系统的性能影响最小
eprof 提供函数运行时间的百分比
fprof 通过将trace存储到文件,提供函数调用计数及运行时间统计信息
这里我们主要介绍fprof,首先其提供的信息最为详细,其次因为将trace存储到文件中,我们可以进行较长运行时间的性能分析
fprof使用
1,fprof:start().
2,
OR
apply在函数开始的时候进行fprof:trace(start, ..),在函数结束的时候执行fprof:trace(stop).上面三个函数都有很多可选参数,默认情况下,使用下面文件保存各阶段信息:fprof.trace, fprof.profile,fprof.analysis
fprof Analysis format
产生了分析报告,最重要的就是如何阅读了。
让我们写一个简单的例子:
进行profiling
analysis结果已经保存到bar.analysis中,此文件可以通过erl_scan and erl_parse, file:consult/1 or io:read/2进行读取分析。
下面我们看看analysis内容:
%% Analysis results:
{ analysis_options,
[{callers, true},
{sort, acc},
{totals, false},
{details, true}]}.
% CNT ACC OWN
[{ totals, 5019, 18.886, 18.884}]. %%%
CNT表示总的函数调用次数,ACC表示Trace起始经历的时间,OWN是Trace中所有函数执行的时间和(不包含调用函数的执行时间),我们这个例子中OWN和ACC比较接近,因为我们这里在启动trace后就立即开始了函数调用,没有进行其他特殊的工作。这里时间的单位为ms。
% CNT ACC OWN
[{ "<0.82.0>", 5019,undefined, 18.884}]. %%
这里表示一个process的开始,在我们这个例子中我们调用fprof:apply/3开始进行trace,因此这个Pid其实就是我们调用apply所在的Process,我们没有Spawn新的Process,所以这里的CNT,OWN和totals相同。ACC的值为undefined,这是因为这个数值对于我们没有什么意义,我们可以通过totals计算出这个数值。
请注意此行结尾处的 “%%”表明一个process的开始
{[{undefined, 0, 18.886, 0.002}],
{ {fprof,apply_start_stop,4}, 0, 18.886, 0.002}, %
[{{bar,test,1}, 1, 18.884, 0.004},
{suspend, 1, 0.000, 0.000}]}.
{[{{fprof,apply_start_stop,4}, 1, 18.884, 0.004}],
{ {bar,test,1}, 1, 18.884, 0.004}, %
[{{lists,map,2}, 1, 14.859, 12.352},
{{lists,splitwith,2}, 1, 3.012, 0.001},
{{lists,seq,2}, 1, 1.009, 0.001}]}.
analysis内容通过空行,间隔成不同的段落。
每个段落中尾部以"%"标记的行为这个段落的标记行。比如上面的内容中{bar,test,1}所在行为一个关键行,此行上面的List为所有调用bar:test/1的函数列表(called list),此行下面的List为bar:test/1调用的函数列表(calling list)。
所有的段落按照ACC递减的顺序排列,同时段落内部的called list和calling list也是按照这个规则排列。
CNT为对应函数累计调用次数,ACC为此函数消耗时间包含其调用的函数,OWN为此函数自身消耗时间不包含called函数。即:
ACC(marked) = OWN(marked) + ACC(calling fun 1) + ACC(calling fun 2) ... ACC(calling fun N)
让我们看看上面的内容中,{bar,test,1}其ACC为:
18.884 = 0.004 + 14.859 + 3.012 + 1.009
同时{bar,test,1}作为我们module的入口其ACC为18.884等于所在process对应的OWN时间。
其实看到这里,我们已经明白,我们这个module中{lists,map,2}最耗时,其占用79% (14.859/18.880)时间,{lists,splitwith,2}占用16% (3.012/18.880) 的时间,而{lists,seq,2} (1.009%18.880) 只占用5%左右。
{[{{bar,test,1}, 1, 14.859, 12.352},
{{lists,map,2}, 1000, 0.000, 1.502}],
{ {lists,map,2}, 1001, 14.859, 13.854}, %
[{{bar,'-test/1-fun-0-',1}, 1000, 1.002, 1.001},
{garbage_collect, 2, 0.002, 0.002},
{suspend, 1, 0.001, 0.000},
{{lists,map,2}, 1000, 0.000, 1.502}]}.
接下来就是依次分析所有的被调用函数,这里说明{lists,map,2}被两个函数调用:
{bar,test,1}和{lists,map,2},也许你有疑问了,在bar:test/1中的确调用了lists:map/2依次,可是我的代码中没有用lists:map/2调用lists:map/2啊,看看stdlib/src/lists.erl代码,你就会明白,lists:map/2是递归方式调用,所以bar module中调用了1次,而我们的List长度是1000,所以lists:map/2函数就被调用了 1 + 1000 = 1001次哦。然后marked行下面就是lists:map/2调用的函数列表。
bar.analysis接下的部分,是对每个函数的分析,如果某个函数为BIF,没有调用任何其他函数,那么其对应的输出内容为:
{[{{lists,reverse,1}, 1, 0.001, 0.001}],
{ {lists,reverse,2}, 1, 0.001, 0.001}, %
[ ]}.
恩,我们lists:reverse/2是BIF,毫无疑问。
在结果中出现了suspend,这是一个pseudo函数,用来说明我们的process此刻处于中止状态,为什么会处于中止状态?我们没有调用erlang:yield/0,也没有调用receive相关的函数,怎么中止了呢?这里是Erlang虚拟机调度的结果,suspend函数对应的ACC时间总是为0,要不要把真正的suspend时间显示出来,这是一个值得争论的问题。
同样的还有garbage_collect函数,其OWN和ACC相同,这里我们把garbage_collect计入了运行时间。
附件是analysis结果,最好自己动手做一下
cprof 提供函数调用计数,其对系统的性能影响最小
eprof 提供函数运行时间的百分比
fprof 通过将trace存储到文件,提供函数调用计数及运行时间统计信息
这里我们主要介绍fprof,首先其提供的信息最为详细,其次因为将trace存储到文件中,我们可以进行较长运行时间的性能分析
fprof使用
1,fprof:start().
2,
fprof:apply fprof:profile fprof:analyse
OR
fprof:trace(start) fprof:trace(stop) fprof:profile fprof:analyse
apply在函数开始的时候进行fprof:trace(start, ..),在函数结束的时候执行fprof:trace(stop).上面三个函数都有很多可选参数,默认情况下,使用下面文件保存各阶段信息:fprof.trace, fprof.profile,fprof.analysis
fprof Analysis format
产生了分析报告,最重要的就是如何阅读了。
让我们写一个简单的例子:
-module(bar). -export([test/1]). test(N) when is_integer(N) -> L = lists:seq(1, N), L2 = lists:map(fun(E) -> E * 2 end, L), _L3 = lists:splitwith(fun(E) -> E rem 2 =:= 0 end, L2), ok.
进行profiling
> c(bar). > fprof:apply(bar, test, [1000]). > fprof:profile(). > fprof:analyse({dest, "bar.analysis"}). Processing data... Creating output... Done! ok
analysis结果已经保存到bar.analysis中,此文件可以通过erl_scan and erl_parse, file:consult/1 or io:read/2进行读取分析。
下面我们看看analysis内容:
引用
%% Analysis results:
{ analysis_options,
[{callers, true},
{sort, acc},
{totals, false},
{details, true}]}.
% CNT ACC OWN
[{ totals, 5019, 18.886, 18.884}]. %%%
CNT表示总的函数调用次数,ACC表示Trace起始经历的时间,OWN是Trace中所有函数执行的时间和(不包含调用函数的执行时间),我们这个例子中OWN和ACC比较接近,因为我们这里在启动trace后就立即开始了函数调用,没有进行其他特殊的工作。这里时间的单位为ms。
引用
% CNT ACC OWN
[{ "<0.82.0>", 5019,undefined, 18.884}]. %%
这里表示一个process的开始,在我们这个例子中我们调用fprof:apply/3开始进行trace,因此这个Pid其实就是我们调用apply所在的Process,我们没有Spawn新的Process,所以这里的CNT,OWN和totals相同。ACC的值为undefined,这是因为这个数值对于我们没有什么意义,我们可以通过totals计算出这个数值。
请注意此行结尾处的 “%%”表明一个process的开始
引用
{[{undefined, 0, 18.886, 0.002}],
{ {fprof,apply_start_stop,4}, 0, 18.886, 0.002}, %
[{{bar,test,1}, 1, 18.884, 0.004},
{suspend, 1, 0.000, 0.000}]}.
{[{{fprof,apply_start_stop,4}, 1, 18.884, 0.004}],
{ {bar,test,1}, 1, 18.884, 0.004}, %
[{{lists,map,2}, 1, 14.859, 12.352},
{{lists,splitwith,2}, 1, 3.012, 0.001},
{{lists,seq,2}, 1, 1.009, 0.001}]}.
analysis内容通过空行,间隔成不同的段落。
每个段落中尾部以"%"标记的行为这个段落的标记行。比如上面的内容中{bar,test,1}所在行为一个关键行,此行上面的List为所有调用bar:test/1的函数列表(called list),此行下面的List为bar:test/1调用的函数列表(calling list)。
所有的段落按照ACC递减的顺序排列,同时段落内部的called list和calling list也是按照这个规则排列。
CNT为对应函数累计调用次数,ACC为此函数消耗时间包含其调用的函数,OWN为此函数自身消耗时间不包含called函数。即:
ACC(marked) = OWN(marked) + ACC(calling fun 1) + ACC(calling fun 2) ... ACC(calling fun N)
让我们看看上面的内容中,{bar,test,1}其ACC为:
18.884 = 0.004 + 14.859 + 3.012 + 1.009
同时{bar,test,1}作为我们module的入口其ACC为18.884等于所在process对应的OWN时间。
其实看到这里,我们已经明白,我们这个module中{lists,map,2}最耗时,其占用79% (14.859/18.880)时间,{lists,splitwith,2}占用16% (3.012/18.880) 的时间,而{lists,seq,2} (1.009%18.880) 只占用5%左右。
引用
{[{{bar,test,1}, 1, 14.859, 12.352},
{{lists,map,2}, 1000, 0.000, 1.502}],
{ {lists,map,2}, 1001, 14.859, 13.854}, %
[{{bar,'-test/1-fun-0-',1}, 1000, 1.002, 1.001},
{garbage_collect, 2, 0.002, 0.002},
{suspend, 1, 0.001, 0.000},
{{lists,map,2}, 1000, 0.000, 1.502}]}.
接下来就是依次分析所有的被调用函数,这里说明{lists,map,2}被两个函数调用:
{bar,test,1}和{lists,map,2},也许你有疑问了,在bar:test/1中的确调用了lists:map/2依次,可是我的代码中没有用lists:map/2调用lists:map/2啊,看看stdlib/src/lists.erl代码,你就会明白,lists:map/2是递归方式调用,所以bar module中调用了1次,而我们的List长度是1000,所以lists:map/2函数就被调用了 1 + 1000 = 1001次哦。然后marked行下面就是lists:map/2调用的函数列表。
bar.analysis接下的部分,是对每个函数的分析,如果某个函数为BIF,没有调用任何其他函数,那么其对应的输出内容为:
引用
{[{{lists,reverse,1}, 1, 0.001, 0.001}],
{ {lists,reverse,2}, 1, 0.001, 0.001}, %
[ ]}.
恩,我们lists:reverse/2是BIF,毫无疑问。
在结果中出现了suspend,这是一个pseudo函数,用来说明我们的process此刻处于中止状态,为什么会处于中止状态?我们没有调用erlang:yield/0,也没有调用receive相关的函数,怎么中止了呢?这里是Erlang虚拟机调度的结果,suspend函数对应的ACC时间总是为0,要不要把真正的suspend时间显示出来,这是一个值得争论的问题。
同样的还有garbage_collect函数,其OWN和ACC相同,这里我们把garbage_collect计入了运行时间。
附件是analysis结果,最好自己动手做一下
- bar.analysis.zip (822 Bytes)
- 下载次数: 38
发表评论
-
Erlang问答网站,欢迎各位提出问题,解答问题。
2012-03-18 15:07 5228平时收到很多关于Erlang的问题,我都尽量一一解答,可是时间 ... -
Emakefile并行编译
2011-11-17 13:15 7598项目代码越来越多,使用erlang编译也越来越慢。无论是Mak ... -
Erlang服务器内存耗尽bug跟踪过程
2011-10-25 21:44 21709本文描述朋友Erlang服务器内存耗尽bug的解决过程 ... -
inet:getstat/2小用法
2011-04-27 09:32 4546inet:getstat/2的用处 在 ... -
Erlang游戏开发-协议
2011-04-22 16:10 10673Erlang游戏开发-协议 ... -
Gearman Erlang Client
2010-10-17 21:14 3677Gearman Gearman是一个通用的任务调度框架。 ... -
ECUG归来
2010-10-17 21:02 2936今天ECUG V圆满结束了,不知不觉作为讲师已经参加过3次大会 ... -
gen-erl-app快速生成erlang app 框架
2010-04-07 14:22 3949经常需要创建各种erlang app,这个过程一旦掌握,就很繁 ... -
erl-redis发布
2010-03-30 11:44 5759最近几天因为需要,实现了一个redis erlang clie ... -
用Erlang做了很多事
2010-01-19 14:08 5036因为工作及时间关系,最近比较忙碌,没有太多的时间写文章。 ... -
ecug topic - erlang开发实践
2009-11-11 10:04 3713从ecug归来,感觉不错,大家学习探讨的积极性很高哦。 很高 ... -
reltool用户指南
2009-11-02 22:27 6292说明,最近比较忙,没有太多时间更新blog,请各位朋友谅解. ... -
Erlang定时任务server (仿crontab语法)
2009-09-23 18:03 6288好久不写blog了,看到yufeng老大那么活跃,我也“耐不住 ... -
Erlang进程之错?
2009-07-27 15:06 3652前阵子erlang-china关于erla ... -
CNode指南
2009-07-27 14:13 3285好久不发文章,因为工作太忙。这个东西就凑凑数吧。各位见谅。 ... -
Erlang类型及函数声明规格
2009-06-08 22:41 9476Erlang类型及函数声明 ... -
使用etop查看系统中进程信息
2009-05-29 13:57 6095Erlang提供了丰富的开发工具,你认为没有的时候,很可能是你 ... -
创建gen_server组解决单process瓶颈
2009-05-27 17:05 5207并发和顺序是一个令人 ... -
又有人投入Erlang的怀抱了:37Signals Campfire loves Erlang
2009-05-14 23:00 3577就喜欢看这样的东西... This is so juicy ... -
list random shuffle实现
2009-05-07 13:41 4318在项目中需要对list进行随机shuffle,但是在erlan ...
相关推荐
PlugFprof 将fprof跟踪添加到Web... 您可以从iex进行分析和分析: iex(1)> :fprof.profile()Reading trace data............End of trace!:okiex(2)> :fprof.analyse([dest: 'analysis.txt', cols: 120, caller
要生成fprof输出,请使用fprof:analyse({dest, "outfile.fprof"}). 。 不要使用总计。 转换为callgrind很简单,只需键入: ./erlgrind_script outfile.fprof outfile.cgrind 。 您的PATH中必须有escript。 然后,您...
它生成Linux 脚本(甚至在Win / macOS上),使用和分析。 它使用调用堆栈采样方法,而不是尝试测量每个单独的调用。 因此,它不需要使用Erlang跟踪(尽管对于某些可选功能它可以使用跟踪)。 它保留呼叫过程信息,...
第五次作业函数第一题--
本项目旨在利用深度学习方法实现作物病害的自动诊断。作物病害是农业生产中的重要问题,及时诊断和处理对于减少产量损失至关重要。 我们采用深度学习算法,通过分析作物的图像,实现对病害的自动识别和分类。项目使用的数据集包括公开的作物病害图像数据集,如ISIC等,并进行了预处理,包括图像增强、分割和特征提取等。 在运行环境方面,我们使用Python编程语言,基于TensorFlow、PyTorch等深度学习框架进行开发。为了提高计算效率,我们还使用了GPU加速计算。此外,我们还采用了Docker容器技术,确保实验结果的可重复性。 项目完成后,将实现对作物病害的快速、准确诊断,为农业生产提供有力支持,有助于减少产量损失。同时,项目成果也可应用于其他图像识别和分类任务。
机械设计CD驱动印刷设备step非常好的设计图纸100%好用.zip
python烟花代码
附件中是一个简单的烟花效果的代码示例: 在Python中,可以使用多种方式来模拟烟花效果,其中一种常用的方法是使用turtle模块,它提供了一个画布和一个小海龟,可以用来绘制各种图形。 这段代码首先导入了turtle模块和random模块,然后在屏幕上绘制了10次烟花爆炸的效果。每次爆炸都是由5个小圆组成,颜色随机选择,圆的大小也是随机的。 请注意,这段代码需要在支持turtle模块的Python环境中运行,并且需要有图形界面的支持。如果你在没有图形界面的环境中(比如某些服务器或者命令行界面),这段代码可能无法正常运行。
商业化产品经理,到底如何实现产品商业化?.docx
Panduit 工业以太网部件内部销售指南
在Java中,实现一个三维装箱(也称为三维背包问题)的算法通常涉及到组合优化和动态规划。这个问题是一个典型的优化问题,其中目标是在三个维度的限制下最大化价值的总和。下面是一个简单的Java代码示例,它使用动态规划来解决三维装箱问题。 请注意,这个代码只是一个简单的示例,它假设所有物品的第三个维度的大小都是1,并且没有给出如何回溯选择物品的完整逻辑。在实际应用中,三维装箱问题可能更加复杂,需要考虑所有三个维度的限制,并且可能需要更复杂的算法来解决。 此外,这个问题的解决方案可能需要根据具体问题的要求进行调整,例如物品是否可以分割、是否允许超过一个的物品等。如果你有特定的问题描述或者需要进一步的帮助,请提供更多的细节。
常用品牌EPLAN部件库
单片机开发的教程可以分为以下几个步骤: 1. 了解单片机基础知识:在学习单片机开发之前,需要了解单片机的相关知识,包括单片机的基本结构、指令系统、编程语言等。 2. 选择开发板:选择一款适合自己学习开发板的型号和厂商,通常需要关注开发板的性价比、开发环境是否友好等因素。 3. 学习开发环境:根据所选的开发板,学习相关的开发环境和使用方法,例如Keil、IAR等集成开发环境。 4. 掌握编程语言:单片机常用的编程语言包括C语言和汇编语言,根据实际情况选择其中一种进行学习。 5. 基础操作:熟悉单片机的引脚定义和IO口配置,了解单片机的启动代码,可以通过修改启动代码进行基本功能调试。 6. 综合实践:根据具体项目需求,进行单片机开发的综合实践。在实践中需要掌握如何编写程序、如何进行硬件调试、如何使用相关工具软件等技能。 下面是一个单片机开发的简单教程介绍: 首先,确定所使用的单片机型号和开发板类型。在这个阶段,需要查阅相关资料,了解开发板的规格书、芯片规格等基本资料。 其次,安装并配置开发环境。根据所选的开发板,安装相应的集成开发环境(IDE),并配置好开发环境。 接着,学习并掌
Q1.ipynb
(自适应手机端)IT网络建站公司pbootcms模板 互联网营销企业网站源码下载.zip
Bematech 激光扫描器用户手册
激励视频接入文档.pdf
java jdk1.8 202版本下载window linux打包
Lite Beam M5快速指南
互联网金融导论.docx