我是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,然后创建一些结果。如果内存的布局首先在第1行存储10个项目,然后在第2行存储10个项目,那么性能可能会更好。
如果有办法控制内存布局?
答案 0 :(得分:6)
矩阵按列存储:
> 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扩展的更多信息,了解如何处理内存。据我所知,没有办法控制内存布局。在它出现问题之前不要担心。
答案 1 :(得分: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
如果您想深入挖掘,colSums
,rowSums
,colMeans
和rowMeans
的代码位于{{1}中的do_colsum
函数中}}