我有一个运行约30分钟的Perl脚本,所以当然我运行Devel :: NYTProf。伟大的探究者。对于我的很多潜艇,我得到的一些数据对我来说没有意义。
我使用默认的NYTProf设置在Linux上使用perl 5.10.0运行。
在HTML输出中,每个subs都有一个摘要部分,说明在子及其子项中花费了多少时间,然后继续给我行信息。
行统计信息不会累计到函数中的总花费。是什么给了什么?
例如,我有一个报告使用233s(57 + 166)的功能。逐行编号报告有一行使用20s,另一行使用4,一行使用2.其他行是< 1s,功能不长。
我该怎么做才能解决这种不匹配问题?
我可以转到Perl 5.12,但这需要一些工作来安装依赖项。我很高兴以较慢的模式运行它。有没有办法增加采样频率?在较慢的机器上运行?
点击此处查看示例:my NYTProf output。在这种情况下,报告子使用225秒,但添加所有数字产生56秒。此次运行已关闭优化:
setenv NYTPROF optimize=0:file=nytprof.optout
更新我使用findcaller = 1选项标记重新运行Perl 5.12,建议或多或少相同的结果。 (我运行了不同的数据集)
更新 Tim B是对的。我已经更改了一些关键子设备来自行缓存,而不是使用memoize,NYTProf结果再次有用。谢谢蒂姆。
答案 0 :(得分:9)
我刚刚将其添加到NYTProf文档中:
= head2如果语句和子例程计时不匹配
NYTProf有两个分析者:一份声明 在perl时调用的分析器 从一个perl语句移动到 另一个,和子程序分析器 当perl调用或调用时调用 从子程序返回。
a的个人陈述时间 子程序通常加起来略有 不到专属的时间 子程序。那是因为 处理子程序调用和 返回开销包含在 子程序的独占时间。该 差异可能只是一个新的 微秒,但可能会变成 对于子程序而言是显而易见的 被召集了数十万次。
语句分析器会跟踪如何进行跟踪 花在开销上的时间很长,比如 将声明配置文件数据写入 磁盘。子程序分析器 减去有的开销 进入和进入之间积累 离开子程序以便 提供更准确的个人资料。该 声明分析器通常非常 快,因为大多数写入得到缓冲 对于zip压缩,所以探查器 每个语句的开销往往是 非常小,通常是一个'滴答'。该 结果就是积累了 开销很吵。这变成了 对于子程序来说更重要 经常被召唤,也是 快速。这可能是另一个,更小, 对差异的贡献 在声明时间和独家之间 次。
这可能解释了语句时间列(31.7s)之和与子程序报告的独占时间(57.2s)之间的差异。差异相当于每次通话约100微秒(这似乎有点高,但并非不合理)。
语句分析器会跟踪开销花费的时间,例如将语句配置文件数据写入磁盘。子程序分析器减去进入和离开子程序之间的开销差异,以便提供更准确的配置文件。
语句分析器通常非常快,因为大多数写入都被缓冲用于zip压缩,因此每个语句的分析器开销往往非常小,通常是单个'tick'。结果是累积的开销非常嘈杂。对于频繁调用且速度很快的子程序(在这种情况下250303调用899μs/调用),这变得更加重要。所以我怀疑这是对陈述时间和独家时间之间差异的另一个较小的贡献。
更重要的是,我还添加了这一部分:
= head2如果标题子例程计时与被叫子计划不匹配
报告总体子程序时间 标题如“花了10s(2 + 8) 在......中。在这个例子中,10 在里面花了几秒钟 子程序(“包容时间”)和, 其中,花了8秒钟 这个子程序调用的子程序。那 留下2秒作为花费的时间 子程序代码本身( “独家时间”,有时也 称为“自我时间”)。
报告显示的源代码 子程序。拨打电话的线路 其他子程序都有注释 详细了解所花费的时间 那些电话。
有时是时间的总和 由代码行中的调用 子程序小于 报道的包容性专属时间 标题(10-2 = 8秒) 上面的例子)。
这里发生的是打电话给 正在制作其他子程序但是 NYTProf无法确定 正确调用位置所以 电话没有出现在报告中 正确的地方。
使用旧版本的perl就是其中之一 原因(see below)。另一个是打电话 通过“goto”退出的子程序 & sub;“ - 最常遇到的 在AUTOLOAD subs和代码中使用Memoize 模块。
一般来说整个子程序 时间是准确的,应该是 信任多于声明的总和 或嵌套的子呼叫时间。
Memoize模块是导致报告不一致的主要原因。对Memoize::__ANON__[...]
的调用执行Memoize生成的子类,看起来像sub { unshift @_, $cref; goto &_memoizer; }
。 goto &_memoizer
由perl实现,作为对调用者的一种返回,然后调用指定的子,这就是NYTProf对其进行配置的方式。
虽然add_bit_to_map
被记录为_memoizer
的来电者,但是呼叫中的时间被添加到add_bit_to_map
,文件和行号会引起混淆。呼叫的位置记录为goto
的位置。
在将来的版本中可能会对此进行改进。
感谢您提示我对此进行调查并改进文档。
蒂姆·邦斯。P.S。我建议在mailing list上询问有关NYTProf的问题。
答案 1 :(得分:2)
尝试禁用perl的优化器。来自CPAN's Devel::NYTProf docs:
优化= 0
禁用perl优化器。
默认情况下,NYTProf会离开perl 优化器已启用。这会给你更多 总体上准确的配置时间,但是 可能导致奇数语句计数 各行各行。那是 因为perl的窥视孔优化器 已经有效地改写了 陈述但你看不出来了 重写版本看起来像。
例如:
1 if (...) { 2 return; 3 } may be rewritten as 1 return if (...)
所以个人资料 不会显示行的语句计数 因为你的源代码中有2个 return被合并到if中 关于前一行的陈述。
使用optimize = 0选项禁用 优化器,所以你会降低 整体表现但更多 准确分配的陈述数。
如果你发现任何其他的例子 优化器对NYTProf输出的影响 (显然除了表演) 请告诉我们。