当前位置: 首页>>代码示例 >>用法及示例精选 >>正文


R Rprof 启用 R 执行分析


R语言 Rprof 位于 utils 包(package)。

说明

启用或禁用执行分析R表达式。

用法

Rprof(filename = "Rprof.out", append = FALSE, interval = 0.02,
       memory.profiling = FALSE, gc.profiling = FALSE,
       line.profiling = FALSE, filter.callframes = FALSE,
       numfiles = 100L, bufsize = 10000L,
       event = c("default", "cpu", "elapsed"))

参数

filename

用于记录分析结果的文件。设置为 NULL"" 以禁用分析。

append

逻辑:文件应该是over-written还是附加到?

interval

real:样本之间的距离(时间间隔),以秒为单位。

memory.profiling

逻辑:将内存使用信息写入文件?

gc.profiling

逻辑:记录GC是否正在运行?

line.profiling

逻辑:将行位置写入文件?

filter.callframes

逻辑:过滤掉调用树的干扰调用帧。请参阅过滤调用帧部分。

numfiles , bufsize

整数:行分析内存分配

event

字符:分析事件,长度为 1 的字符向量,"elapsed" 表示经过的时间(实际,wall-clock),"cpu" 表示 CPU 时间,均以秒为单位。 "default" 是平台上的默认事件,两者之一。请参阅“详细信息”。

细节

自动启用分析会禁用对另一个或同一文件的任何现有分析。

分析的工作原理是每隔 interval 秒(分析事件的单位)将调用堆栈写入指定的文件。 summaryRprof 函数或包装脚本 R CMD Rprof 可用于处理输出文件以生成使用情况摘要;使用 R CMD Rprof --help 获取使用信息。

确切测量的内容很微妙,并且取决于分析事件。

"elapsed"(Windows 上默认且唯一受支持的事件):是时候了R进程正在运行并执行R命令。然而,这不仅仅是 CPU 时间,因为如果readline()正在等待输入,这也很重要。它也称为‘elapsed’ 时间。

"cpu"(Unix 上的默认值,通常是识别性能瓶颈的首选事件),它是R过程,因此例如排除时间R正在等待输入或运行的进程system返回。它可能会慢于"elapsed"当进程经常等待 I/O 完成时,但在多核系统上主动计算并发线程(例如通过 OpenMP)可能会更快。

注意(定时)间隔不能太小。对于 "cpu" ,每个分析步骤所花费的时间当前已添加到间隔中。对于所有分析事件,每个分析步骤中的计算都会对观察到的系统造成扰动并使结果产生偏差。可行的是machine-dependent。在 Linux 上,R 要求间隔至少为 10 毫秒,在所有其他平台上至少为 1 毫秒。较短的间隔将被四舍五入并带有警告。

"default" 分析事件在 Windows 上为 "elapsed",在 Unix 上为 "cpu"

支持"elapsed"Unix 上的事件是新的并且被认为是实验性的。为了降低丢失样本的风险,R 尝试使用(实时)FIFO 调度策略,并为启动每个样本收集的内部线程提供最大调度优先级。如果设置该优先级失败,则尝试使用当前调度策略的最大调度优先级,回退到当前调度参数。在 Linux 上,普通用户通常不允许使用实时调度优先级。这通常可以通过 PAM 允许(例如‘/etc/security/limits.conf’),有关详细信息,请参阅操作系统文档。仅当分析高负载下的系统时,优先级才重要。

仅当函数在调用堆栈上放置上下文时,函数才会记录在配置文件日志中(请参阅 sys.calls )。某些 primitive 函数不会这样做:特别是 type "special" 的函数(有关更多详细信息,请参阅“R 内部”手册)。

如果 line.profilingTRUE ,并且正在执行的代码是使用源引用进行解析的,则各个语句将记录在配置文件日志中。有关源参考的讨论,请参阅parse。默认情况下,语句位置不会显示在 summaryRprof 中,但请参阅帮助页面以获取启用显示的选项。

过滤掉调用帧

延迟求值使调用堆栈变得更加复杂,因为在将参数应用于函数的时间和有效求值它们的时间之间创建了中间调用帧。当调用堆栈表示为树时,这些中间帧显示为同级节点。例如,在计算 EXPR 时,计算 try(EXPR) 会生成以下调用树:

1. +-base::try(EXPR)
2. | \-base::tryCatch(...)
3. |   \-base:::tryCatchList(expr, classes, parentenv, handlers)
4. |     \-base:::tryCatchOne(expr, names, parentenv, handlers[[1L]])
5. |       \-base:::doTryCatch(return(expr), name, parentenv, handler)
6. \-EXPR

第 2 行到第 5 行是干预调用帧,最后一个调用帧最终触发了 EXPR 的求值。将 filter.callframes 设置为 TRUE 可通过删除介入帧的所有同级节点来简化探查器输出。

eval() 帧应用了相同类型的调用帧过滤。当您调用 eval() 时,会将两个帧压入堆栈以确保帧之间的连续性。假设我们有这些定义:

calling <- function() evaluator(quote(called()), environment())
evaluator <- function(expr, env) eval(expr, env)
called <- function() EXPR()

calling() 通过 eval() 在自己的环境中调用 called() 。后者通过 evaluator() 间接调用。此代码的最终效果与直接调用 called() 相同,无需中介。然而,完整的调用堆栈如下所示:

1. calling()
2. \-evaluator(quote(called()), environment())
3.   \-base::eval(expr, env)
4.     \-base::eval(expr, env)
5.       \-called()
6.         \-EXPR()

当调用帧过滤打开时,会查找called()的真实调用环境,过滤后的调用堆栈如下所示:

1. calling()
5. \-called()
6.   \-EXPR()

如果调用环境不在堆栈上,则eval()调用的函数成为根节点。假设我们有:

calling <- function() evaluator(quote(called()), new.env())

通过调用帧过滤,我们得到以下过滤后的调用堆栈:

5. called()
6. \-EXPR()

注意

在 Unix 类系统上:

分析并非在所有平台上都可用。默认情况下,如果可能的话,会编译对分析的支持 - 配置R--disable-R-profiling改变这一点。

作为RCPU 分析使用与 C 分析相同的机制,两者不能一起使用,因此不要使用Rprof(event = "cpu")(默认)在为 C-level 分析构建的可执行文件中(例如使用 GCC 选项-p或者-pg)。

在 Windows 上:

filename 可以是无法转换为当前区域设置的 UTF-8 编码文件路径。

探查器会异步中断 R,并且它无法在运行时分配内存来存储结果。这会影响行分析,它需要存储未知数量的文件路径名。 numfilesbufsize 参数控制预分配缓冲区的大小以保存这些结果:前者计算路径的最大数量,后者计算路径中的字节数。如果分析器用完空间,它将跳过记录新文件的行信息,并在调用 Rprof(NULL) 完成分析时发出警告。

例子

## Not run: Rprof()
## some code to be profiled
Rprof(NULL)
## some code NOT to be profiled
Rprof(append = TRUE)
## some code to be profiled
Rprof(NULL)
## ...
## Now post-process the output as described in Details

## End(Not run)

也可以看看

“编写 R 扩展”中的“整理和分析 R 代码”一章(请参阅“文档/手册’的子目录R源树)。

summaryRprof 分析输出文件。

tracememRprofmem 用于跟踪内存使用的其他方法。

相关用法


注:本文由纯净天空筛选整理自R-devel大神的英文原创作品 Enable Profiling of R's Execution。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。