公式 return 的 R 函数具有较大的内存印记
R function with formula return has large memory imprint
我有一个适合模型的函数,我用同一个大矩阵调用了很多次(每次都在内部创建不同的公式)。但是,R 似乎保存了我一路上使用的数据的副本,所以我的内存爆炸了。
函数内部的一个简单删除就避免了这个问题。 但是,有没有一种通用的方法可以避免每次都保留整个环境?
例如运行以下,
test <- function(X, y, rm.env=F){
df <- cbind(y, X)
names(df) <- c("label", paste0("X", as.character(1:ncol(X))))
f <- formula(label~1, data=df, env=emptyenv())
if (rm.env){
rm(list=c("df", "X", "y"))
}
print(pryr::object_size(f))
return(f)
}
X <- matrix(rnorm(700*10000), ncol=700)
y <- rnorm(10000)
m <- test(X, y)
print(pryr::object_size(m))
m <- test(X, y, rm.env=T)
print(pryr::object_size(m))
结果,
672 B
168 MB
672 B
1.13 kB
请注意,第一次调用中的对象后面有 168 MB,因此一遍又一遍地调用第一个版本会很快吃掉大量内存。
formula(label~1, data=df, env=emptyenv())
调用 S3 方法 formula.formula
。我们来看看它的代码:
stats:::formula.formula
# function (x, ...)
# x
…忽略多余的参数!
换句话说,您的作业与您只写 f = label ~ 1
相同。特别是,它的关联环境是本地环境,而不是空环境。要解决此问题,您需要手动重置它:
test <- function (X, y) {
df <- cbind(y, X)
names(df) <- c("label", paste0("X", seq_along(X)))
# TODO: do something with `df` …
f <- label ~ 1
environment(f) <- emptyenv()
f
}
我有一个适合模型的函数,我用同一个大矩阵调用了很多次(每次都在内部创建不同的公式)。但是,R 似乎保存了我一路上使用的数据的副本,所以我的内存爆炸了。
函数内部的一个简单删除就避免了这个问题。 但是,有没有一种通用的方法可以避免每次都保留整个环境?
例如运行以下,
test <- function(X, y, rm.env=F){
df <- cbind(y, X)
names(df) <- c("label", paste0("X", as.character(1:ncol(X))))
f <- formula(label~1, data=df, env=emptyenv())
if (rm.env){
rm(list=c("df", "X", "y"))
}
print(pryr::object_size(f))
return(f)
}
X <- matrix(rnorm(700*10000), ncol=700)
y <- rnorm(10000)
m <- test(X, y)
print(pryr::object_size(m))
m <- test(X, y, rm.env=T)
print(pryr::object_size(m))
结果,
672 B
168 MB
672 B
1.13 kB
请注意,第一次调用中的对象后面有 168 MB,因此一遍又一遍地调用第一个版本会很快吃掉大量内存。
formula(label~1, data=df, env=emptyenv())
调用 S3 方法 formula.formula
。我们来看看它的代码:
stats:::formula.formula
# function (x, ...)
# x
…忽略多余的参数!
换句话说,您的作业与您只写 f = label ~ 1
相同。特别是,它的关联环境是本地环境,而不是空环境。要解决此问题,您需要手动重置它:
test <- function (X, y) {
df <- cbind(y, X)
names(df) <- c("label", paste0("X", seq_along(X)))
# TODO: do something with `df` …
f <- label ~ 1
environment(f) <- emptyenv()
f
}