加速 R 中的数组访问

发布于 2025-01-16 15:15:50 字数 2682 浏览 0 评论 0原文

我的 R 代码有一对相对较慢的数组访问步骤,我想加快速度。本质上,它看起来像这样:

termsA = matrix(data = NA,nrow = nrow(matLargeA),ncol = 15)

termsB = energy.terms
for (j in 1:15){
            
            termsA[,j] = matSmall[matLargeA[,j],j] #***
            
            termsB[,j] = matSmall[matLargeB[,j],j] #***
            

}

rowsA = rowSums(termsA)
rowsB = rowSums(termsB)

我试图加速的行是以 #*** 结尾的行

matSmall 是一个 4 x 15 非负双精度矩阵。它基本上是任意的:唯一奇怪的事情是每一列中必须恰好有一个零元素,并且所有元素都小于 4。否则,列不会以任何方式相互关联。

matLargeAmatLargeB 都是 1000s x 15 双精度矩阵,其条目是整数 1 到 4。但是,它们不是任意排列的:每个矩阵都基于不同的序列整数 1 到 4,行是该序列的 15 个元素窗口。例如:

> matLargeA[1:17,]
      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13]
 [1,]    3    4    3    1    1    3    2    2    3     3     3     1     1
 [2,]    4    3    1    1    3    2    2    3    3     3     1     1     3
 [3,]    3    1    1    3    2    2    3    3    3     1     1     3     2
 [4,]    1    1    3    2    2    3    3    3    1     1     3     2     3
 [5,]    1    3    2    2    3    3    3    1    1     3     2     3     3
 [6,]    3    2    2    3    3    3    1    1    3     2     3     3     1
 [7,]    2    2    3    3    3    1    1    3    2     3     3     1     2
 [8,]    2    3    3    3    1    1    3    2    3     3     1     2     3
 [9,]    3    3    3    1    1    3    2    3    3     1     2     3     1
[10,]    3    3    1    1    3    2    3    3    1     2     3     1     3
[11,]    3    1    1    3    2    3    3    1    2     3     1     3     3
[12,]    1    1    3    2    3    3    1    2    3     1     3     3     1
[13,]    1    3    2    3    3    1    2    3    1     3     3     1     4
[14,]    3    2    3    3    1    2    3    1    3     3     1     4     2
[15,]    2    3    3    1    2    3    1    3    3     1     4     2     4
[16,]    3    3    1    2    3    1    3    3    1     4     2     4     1
[17,]    3    1    2    3    1    3    3    1    4     2     4     1     3
      [,14] [,15]
 [1,]     3     2
 [2,]     2     3
 [3,]     3     3
 [4,]     3     1
 [5,]     1     2
 [6,]     2     3
 [7,]     3     1
 [8,]     1     3
 [9,]     3     3
[10,]     3     1
[11,]     1     4
[12,]     4     2
[13,]     2     4
[14,]     4     1
[15,]     1     3
[16,]     3     4
[17,]     4     4 

我主要需要 rowsA 和 rowsB 来完成程序其余部分的操作。但是,我首先安排代码生成 termsAtermsB 因为执行这种列优先类型访问比执行行优先类型访问要快得多:它是一个我所做的第一个主要优化。标有 #*** 的数组访问行是一组代码中的最后一个主要瓶颈,我确实希望快速运行这些代码,因为代码使用这些行运行函数的时间约为 O(10^7 )次,即使是很小的加速也会极大地影响我的运行时间。我 99% 确信这是一种内存访问类型减慢,但我没有看到一种简单的方法可以使其更快。那么如何才能使内存访问更快呢?

I have R code that has a pair of relatively slow array access steps that I want to speed up. Essentially, it looks something like this:

termsA = matrix(data = NA,nrow = nrow(matLargeA),ncol = 15)

termsB = energy.terms
for (j in 1:15){
            
            termsA[,j] = matSmall[matLargeA[,j],j] #***
            
            termsB[,j] = matSmall[matLargeB[,j],j] #***
            

}

rowsA = rowSums(termsA)
rowsB = rowSums(termsB)

The lines I'm trying to speed up are the ones that end in #***

matSmall is a 4 x 15 matrix of nonnegative doubles. It is mostly arbitrary: the only weird things about it are that is must have exactly one zero element in each column, and all elements are less than 4. Otherwise, the columns do not relate to each other in any way.

Both matLargeA and matLargeB are 1000s x 15 matrices of doubles whose entries are the integers 1 through 4. However, they are NOT arbitrarily arranged: each matrix is based on a different sequence of integers 1 through 4, and the rows are 15 element windows of that sequence. For example:

> matLargeA[1:17,]
      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13]
 [1,]    3    4    3    1    1    3    2    2    3     3     3     1     1
 [2,]    4    3    1    1    3    2    2    3    3     3     1     1     3
 [3,]    3    1    1    3    2    2    3    3    3     1     1     3     2
 [4,]    1    1    3    2    2    3    3    3    1     1     3     2     3
 [5,]    1    3    2    2    3    3    3    1    1     3     2     3     3
 [6,]    3    2    2    3    3    3    1    1    3     2     3     3     1
 [7,]    2    2    3    3    3    1    1    3    2     3     3     1     2
 [8,]    2    3    3    3    1    1    3    2    3     3     1     2     3
 [9,]    3    3    3    1    1    3    2    3    3     1     2     3     1
[10,]    3    3    1    1    3    2    3    3    1     2     3     1     3
[11,]    3    1    1    3    2    3    3    1    2     3     1     3     3
[12,]    1    1    3    2    3    3    1    2    3     1     3     3     1
[13,]    1    3    2    3    3    1    2    3    1     3     3     1     4
[14,]    3    2    3    3    1    2    3    1    3     3     1     4     2
[15,]    2    3    3    1    2    3    1    3    3     1     4     2     4
[16,]    3    3    1    2    3    1    3    3    1     4     2     4     1
[17,]    3    1    2    3    1    3    3    1    4     2     4     1     3
      [,14] [,15]
 [1,]     3     2
 [2,]     2     3
 [3,]     3     3
 [4,]     3     1
 [5,]     1     2
 [6,]     2     3
 [7,]     3     1
 [8,]     1     3
 [9,]     3     3
[10,]     3     1
[11,]     1     4
[12,]     4     2
[13,]     2     4
[14,]     4     1
[15,]     1     3
[16,]     3     4
[17,]     4     4 

I mainly need rowsA and rowsB for what I'm trying to do in the rest of the program. But, I arranged the code to generate termsA and termsB first because doing this sort of column first type access is a LOT faster than doing the row first type access: it was one of the first major optimizations I did. The array access lines marked with #*** are the last major bottleneck in a set of code that I would really prefer run quickly, because the code runs the function with this lines around O(10^7) times, and even minor speedups will impact my run time substantially. I'm like 99% sure that this is a memory access type slow down, but I don't see an easy way to make it faster. So how can I make this memory access faster?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文