如何在 R 中分析和优化已经快速的代码

Posted

技术标签:

【中文标题】如何在 R 中分析和优化已经快速的代码【英文标题】:How to profile and optimise already fast code in R 【发布时间】:2020-07-28 22:19:37 【问题描述】:

我在 R 中有一个要优化的函数。它是最内层循环的一部分,所以它运行了数百万次,我从分析中知道这个函数占用了总计算时间的 80%。

我一直在使用 profvis 包来了解我的代码在哪里运行缓慢,并且通过进行渐进式改进,现在只需不到 10 毫秒的时间即可运行该函数。

但此时,profvis 停止工作,并且没有提供有用的细分,说明哪些代码行使用的时间最多。例如:

func <- function(x)
  x1 <- x ** 2
  x2 <- x * 3
  x3 <- sum(1:x)
  x4 <- x1 + x2 + x3

profvis::profvis(func(10))
Error in parse_rprof(prof_output, expr_source) : 
  No parsing data available. Maybe your function was too fast?

他们的替代包或方法是否可以很好地分析运行时间少于 10 毫秒的函数?

【问题讨论】:

【参考方案1】:

profvis 使用Rprof,因此您可能想在?Rprof 阅读有关其限制的信息。

如果所有其他方法都失败了,您可以进行小规模实验:更改函数中的某些内容(例如减少赋值次数),然后测量调用函数的循环的总运行时间。这会因您的编译器设置而有些复杂(请参阅?compiler::compile)。但是您有一个终极方法来查看某些更改是否有帮助:运行您的代码(多次),看看它是否变得更快。

func <- function(x)
  x1 <- x ** 2
  x2 <- x * 3
  x3 <- sum(1:x)
  x4 <- x1 + x2 + x3

func2 <- function(x)
  x*x + x*3 + sum(seq_len(x)) 


library("compiler")
ii <- 1:1000000
enableJIT(0) 
system.time(for (i in ii) func (100))
system.time(for (i in ii) func2(100))

enableJIT(3) 
system.time(for (i in ii) func (100))
system.time(for (i in ii) func2(100))

【讨论】:

以上是关于如何在 R 中分析和优化已经快速的代码的主要内容,如果未能解决你的问题,请参考以下文章

如何分析 Rcpp 代码(在 linux 上)

在解构中分配选项[重复]

如何在 Python 中分析内存使用情况?

如何在 Python 中分析内存使用情况?

如何在 R 中分析不规则的时间序列

如何从启用优化(发布模式)构建的二进制文件中分析故障转储?