【问题标题】:data frame (matrix) performance: memory layout数据框(矩阵)性能:内存布局
【发布时间】:2011-01-19 09:15:53
【问题描述】:

我是 R 的新手。假设数据框和矩阵的内存布局相同。

在下面的矩阵中

a=矩阵(1:10000000,1000000,10)

它有 1M 行和 10 列。行或列的内存是物理顺序的吗?或者是物理内存先存储[1,1],[2,1],[3,1],,[1M,1],[2,1]还是[1,2],[1,2], ..[1,10],[2,1]...?

假设10M元素的矩阵大小为100M,L2缓存为4M,则L2缓存无法存储所有这10M元素。如果我们按顺序处理数据,我们将有更少的 L2 缓存丢失率。对于我们的案例,我们需要逐行处理并同时读取几列,例如列A、B、C,然后创建一些结果。如果内存的布局是先在第一行存储 10 个项目,然后在第二行存储 10 个项目,那么性能可能会更好。

有没有办法控制内存布局?

【问题讨论】:

  • 您可以尝试比较使用at(a) 的性能,看看行/列是否有很大的影响。

标签: r


【解决方案1】:

矩阵按列存储:

> m=matrix(1:12,nrow=3)
> m
     [,1] [,2] [,3] [,4]
[1,]    1    4    7   10
[2,]    2    5    8   11
[3,]    3    6    9   12

数据框只是漂亮的列表,列表存储为元素的向量。我什至不确定列表元素是否保证在内存中是连续的。

阅读编写 R 扩展以获取有关如何处理内存的更多信息。据我所知,没有办法控制内存布局。在它成为问题之前不要担心它。

【讨论】:

    【解决方案2】:

    矩阵只是一个带有dim 属性的向量。矩阵的元素以列优先顺序存储在向量中。没有办法改变这一点。

    因此,如果您需要逐行操作,在循环之前转置矩阵会更快。

    > set.seed(21)
    > a = matrix(rnorm(1e6),1e3,1e3)
    > ta = t(a)
    > system.time(for(i in 1:1000) colSums(ta))
       user  system elapsed 
       1.39    0.00    1.40 
    > system.time(for(i in 1:1000) rowSums(a))
       user  system elapsed 
       2.40    0.00    2.39 
    > identical(rowSums(a), colSums(ta))
    [1] TRUE
    

    如果您想深入挖掘,colSumsrowSumscolMeansrowMeans 的代码在 do_colsum 函数中,位于 src/main/array.c 中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多