R 替换值时,矩阵将内存使用率提高一倍
如果替换矩阵中的值,为什么矩阵的大小会加倍?我可以阻止R这样做吗? 例如:R 替换值时,矩阵将内存使用率提高一倍,r,memory-management,matrix,replace,R,Memory Management,Matrix,Replace,如果替换矩阵中的值,为什么矩阵的大小会加倍?我可以阻止R这样做吗? 例如: set.seed(42) 0x7fe9c2d2bf70]: a[,swapcol][swapmat==0]0x7fe9c2e1b460]: 对象。大小(a)/1024/1024 #0.076MB,内存占用翻倍 我知道矩阵可能会被复制以替换值,但为什么它会变大?(replace()导致了同样的行为)我读了哈德利的书中关于这个问题的章节,以及这个问题的答案,但我仍然想知道为什么会发生这种情况。我想也许R需要更多的操作系统空
set.seed(42)
0x7fe9c2d2bf70]:
a[,swapcol][swapmat==0]0x7fe9c2e1b460]:
对象。大小(a)/1024/1024
#0.076MB,内存占用翻倍
我知道矩阵可能会被复制以替换值,但为什么它会变大?(replace()导致了同样的行为)我读了哈德利的书中关于这个问题的章节,以及这个问题的答案,但我仍然想知道为什么会发生这种情况。我想也许R需要更多的操作系统空间,以防我想放大矩阵,但是为什么要增加两倍的空间呢?对于大型矩阵,这甚至是正确的(使用相同的因子),这使得我的系统交换内存(从而与潜在的节省时间效果相矛盾)
谢谢你的提示 将评论转换为答案:
set.seed(42)
> a <- matrix(rbinom(10000,2,0.45),ncol=10)
> object.size(a)/1024/1024
0.0383377075195312 bytes
> swapcol <- colMeans(a)>1
> swapmat <- a[,swapcol]
> tracemem(a)
[1] "<0x7fc50ec45e00>"
> a[,swapcol][swapmat==2] <- 0L
tracemem[0x7fc50ec45e00 -> 0x7fc50d839e00]:
> a[,swapcol][swapmat==0] <- 2L
> object.size(a)/1024/1024
0.0383377075195312 bytes
set.seed(42)
>a对象。大小(a)/1024/1024
0.0383377075195312字节
>swapcol 1
>swapmat轨迹图(a)
[1] ""
>a[,swapcol][swapmat==2]0x7fc50d839e00]:
>a[,swapcol][swapmat==0]对象。大小(a)/1024/1024
0.0383377075195312字节
同样大小 将评论转换为答案:
set.seed(42)
> a <- matrix(rbinom(10000,2,0.45),ncol=10)
> object.size(a)/1024/1024
0.0383377075195312 bytes
> swapcol <- colMeans(a)>1
> swapmat <- a[,swapcol]
> tracemem(a)
[1] "<0x7fc50ec45e00>"
> a[,swapcol][swapmat==2] <- 0L
tracemem[0x7fc50ec45e00 -> 0x7fc50d839e00]:
> a[,swapcol][swapmat==0] <- 2L
> object.size(a)/1024/1024
0.0383377075195312 bytes
set.seed(42)
>a对象。大小(a)/1024/1024
0.0383377075195312字节
>swapcol 1
>swapmat轨迹图(a)
[1] ""
>a[,swapcol][swapmat==2]0x7fc50d839e00]:
>a[,swapcol][swapmat==0]对象。大小(a)/1024/1024
0.0383377075195312字节
同样大小 问题在于
0
,2
等对于R而言不是整数而是双倍数,当您将它们分配给矩阵a
的元素时,您强制R使用双倍数存储修改后的a
,这会增加对象的内存大小。原始a
使用整数存储,每个整数占用的内存更少。您可以通过storage.mode()
看到这一点:
问题在于,
0
,2
等对于R而言不是整数而是双倍数,当您将它们分配给矩阵a
的元素时,您强制R使用双倍数存储修改后的a
,这会增加对象的内存大小。原始a
使用整数存储,每个整数占用的内存更少。您可以通过storage.mode()
看到这一点:
0
和2
是浮动(即双倍)。你的矩阵包含整数。使用0L
和2L
强制R将它们视为整数。谢谢!成功了。然而有点出乎意料。。。我还有很多东西要学。如果你用一个非常简短的答案来表述它,我会接受它。你也可能对typeof()
感兴趣,比如typeof(swapmat)
和typeof(4);类型(4L);typeof(1:4)
等@GavinSimpson——是的。在我看到你的答案之前就发布了。看到这两个并排的对象(并再次思考它们之间的区别)确实激发了我前段时间的重温。@Andarin R必须假设一些关于值的东西,因为我们在创建对象时不在R中键入对象,这与其他一些语言不同。惯例是假设双倍,这可能是因为对于统计而言,可能需要在各种例程中对数据进行双倍计算。0
和2
是浮动(即双倍)。你的矩阵包含整数。使用0L
和2L
强制R将它们视为整数。谢谢!成功了。然而有点出乎意料。。。我还有很多东西要学。如果你用一个非常简短的答案来表述它,我会接受它。你也可能对typeof()
感兴趣,比如typeof(swapmat)
和typeof(4);类型(4L);typeof(1:4)
等@GavinSimpson——是的。在我看到你的答案之前就发布了。看到这两个并排的对象(并再次思考它们之间的区别)确实激发了我前段时间的重温。@Andarin R必须假设一些关于值的东西,因为我们在创建对象时不在R中键入对象,这与其他一些语言不同。惯例是假设双倍,可能是因为对于统计而言,可能需要在各种例程中进行数据双倍的计算。感谢您提供了非常详细的答案!(关于格式(object.size)
..的提示)我认为它的行为更像C,只有在必要时才转换为double
(2是int
),尽管我认为R将一切都视为double
。然而,我的二项式矩阵被创建为int
,而不是一个基本int
s的向量,这让我感到惊讶(例如typeof(rbinom(3,1,1))
vstypeof(rep(1,3))
),谢谢你详细的回答!(关于格式(object.size)
..的提示)我认为它的行为更像C,只有在必要时才转换为double
(2是int
),尽管我认为R将一切都视为double
。然而,我的二项式矩阵被创建为int
,而不是一个基本int
s的向量,这让我感到惊讶(例如typeof(rbinom(3,1,1))
vstypeof(rep(1,3))
)。
set.seed(42)
a <- matrix(rbinom(10000,2,0.45),ncol=10)
> storage.mode(a)
[1] "integer"
swapcol <- colMeans(a)>1
swapmat <- a[,swapcol]
a[,swapcol][swapmat==2] <- 0
a[,swapcol][swapmat==0] <- 2
> storage.mode(a)
[1] "double"
> format(object.size(a), units = "Kb")
[1] "78.3 Kb"
set.seed(42)
a <- matrix(rbinom(10000,2,0.45),ncol=10)
swapcol <- colMeans(a)>1
swapmat <- a[,swapcol]
a[,swapcol][swapmat==2] <- 0L
a[,swapcol][swapmat==0] <- 2L
> storage.mode(a)
[1] "integer"
> format(object.size(a), units = "Kb")
[1] "39.3 Kb"