首页 > 解决方案 > 如何加快写入R中参考类中的矩阵

问题描述

这是一段 R 代码,它写入参考类中矩阵的每个元素。它运行得非常慢,我想知道我是否错过了一个可以加快速度的简单技巧。

nx = 2000
ny = 10
ref_matrix <- setRefClass(
   "ref_matrix",fields = list(data  = "matrix"),
)
out <- ref_matrix(data = matrix(0.0,nx,ny))
#tracemem(out$data)
for (iy in 1:ny) {
   for (ix in 1:nx) {
      out$data[ix,iy] <- ix + iy
   }
}

似乎每次写入矩阵元素都会触发涉及整个矩阵副本的检查。(取消注释 tracemen() 调用显示了这一点。)现在,我发现一个似乎证实了这一点的讨论: https ://r-devel.r-project.narkive.com/8KtYICjV/rd-copy-on-assignment -to-large-field-of-reference-class ,这似乎也被加速 R 引用类中的字段访问所涵盖, 但是在这两种情况下,可以通过不为该字段声明类来绕过这种行为,这很有效对于使用一维向量 b 的第一个链接中的示例,可以将其设置为 b <<- 1:10000。但是我还没有找到一种不使用显式“矩阵”实例来创建二维数组的等效方法。

我只是错过了一些简单的东西,还是这实际上不可能?

让我补充几点。首先,我对 R 很陌生,所以很容易错过一些东西。其次,我真的很好奇引用类在这种情况下的工作方式以及是否有一种简单的方法可以有效地使用它们;我不是在寻找一种非常快速的方法来设置矩阵的元素 - 我可以通过在参考类中完全没有矩阵来做到这一点,如果我真的关心速度,我可以编写一个 C 例程来做到这一点并从 R 调用它。

这里有一些背景可以解释我为什么对此感兴趣,欢迎您忽略。

我想看看不同的语言,甚至不同的编译器选项和编码相同操作的不同方式,在访问 2D 矩形数组时如何比较效率。我一直在玩一个测试程序,它创建两个相同大小的二维数组,并调用一个子程序,将第一个设置为第二个的元素加上它们的索引值。(几乎任何操作都可以,但优化起来并不完全是微不足道的。)我现在在多种语言中都有这个,C、C++、Julia、Tcl、Fortran、Swift 等,甚至是手工编码的汇编程序(剧透警告:汇编程序不再值得努力)并认为我会尝试 R。R 中的明显实现将两个数组传递给完成工作的子例程,但因为 R 通常不通过引用传递,该例程必须复制修改后的数组并将其作为函数值返回。我认为使用引用类可以避免该副本的相对较小的开销,所以我尝试了这一点,并惊讶地发现,它不仅没有加快速度,反而大大减慢了速度。

标签: rmatrixreference-class

解决方案


使用outer

out$data <- outer(1:ny, 1:nx, `+`)

此外,除非您确实需要引用语义,否则不要使用引用类(或 R6 类)。亲吻等等。


推荐阅读