为什么一个环境的 `object.size` 比环境中 objects 的 `object.size` 小?
Why is the `object.size` of an environment smaller than the `object.size` of the objects in the environment?
我 运行 在编写函数工厂时遇到了困惑。我有一个带有识别信息列的标题,以及一个包含数据的列表列。
tib <-
tibble(
id_1 = letters[1:3],
id_2 = LETTERS[1:3],
data = list(mtcars, iris, volcano)
)
我创建了一个函数工厂,以便轻松获取存储在此 tibble 中的数据集。
data_getter <- function(data) {
force(data)
function(id_1, id_2) {
where <- data$id_1 == id_1 & data$id_2 == id_2
data[where, ]$data %>%
purrr::flatten_df()
}
}
get_from_tib <- data_getter(tib)
实际上,我正在使用的数据框非常大。我的理解是 get_from_tib
捕获包含 tib
的环境。当我这样做时,我担心通过复制这个大数据集,我会开始 运行 内存不足。然而,当我的函数的 object.size
小于它应该捕获的数据集时,我感到非常惊讶!
object.size(tib)
21752 bytes
object.size(get_from_tib)
8416 bytes
即使我从工作环境
中删除tib
,这仍然有效
rm(tib)
object.size(get_from_tib)
8416 bytes
为什么环境变小了? object.size
只是获取环境中包含的所有 objects 大小的错误函数吗?
下面的 Reprex
library(magrittr)
tib <-
dplyr::tibble(
id_1 = letters[1:3],
id_2 = LETTERS[1:3],
data = list(mtcars, iris, USArrests)
)
data_getter <- function(data) {
force(data)
function(id_1, id_2) {
where <- data$id_1 == id_1 & data$id_2 == id_2
data[where, ]$data %>%
purrr::flatten_df()
}
}
get_from_tib <- data_getter(tib)
get_from_tib('c', 'C')
#> # A tibble: 50 x 4
#> Murder Assault UrbanPop Rape
#> <dbl> <int> <int> <dbl>
#> 1 13.2 236 58 21.2
#> 2 10 263 48 44.5
#> 3 8.1 294 80 31
#> 4 8.8 190 50 19.5
#> 5 9 276 91 40.6
#> 6 7.9 204 78 38.7
#> 7 3.3 110 77 11.1
#> 8 5.9 238 72 15.8
#> 9 15.4 335 80 31.9
#> 10 17.4 211 60 25.8
#> # … with 40 more rows
object.size(tib)
#> 21752 bytes
object.size(get_from_tib)
#> 8416 bytes
rm(tib)
object.size(get_from_tib)
#> 8416 bytes
由 reprex package (v0.2.1)
于 2019-04-30 创建
这与 ?object.size
帮助页面中的
部分有关
Associated space (e.g., the environment of a function and what the pointer in a EXTPTRSXP points to) is not included in the calculation.
data
变量在闭包中被捕获;它并不是 "in" 从 data_getter
.
返回的函数代码
pyry::object_size()
函数在考虑封闭环境方面做得更好。
pryr::object_size(tib)
# 21 kB
pryr::object_size(get_from_tib)
# 26.9 kB
我 运行 在编写函数工厂时遇到了困惑。我有一个带有识别信息列的标题,以及一个包含数据的列表列。
tib <-
tibble(
id_1 = letters[1:3],
id_2 = LETTERS[1:3],
data = list(mtcars, iris, volcano)
)
我创建了一个函数工厂,以便轻松获取存储在此 tibble 中的数据集。
data_getter <- function(data) {
force(data)
function(id_1, id_2) {
where <- data$id_1 == id_1 & data$id_2 == id_2
data[where, ]$data %>%
purrr::flatten_df()
}
}
get_from_tib <- data_getter(tib)
实际上,我正在使用的数据框非常大。我的理解是 get_from_tib
捕获包含 tib
的环境。当我这样做时,我担心通过复制这个大数据集,我会开始 运行 内存不足。然而,当我的函数的 object.size
小于它应该捕获的数据集时,我感到非常惊讶!
object.size(tib)
21752 bytes
object.size(get_from_tib)
8416 bytes
即使我从工作环境
中删除tib
,这仍然有效
rm(tib)
object.size(get_from_tib)
8416 bytes
为什么环境变小了? object.size
只是获取环境中包含的所有 objects 大小的错误函数吗?
下面的 Reprex
library(magrittr)
tib <-
dplyr::tibble(
id_1 = letters[1:3],
id_2 = LETTERS[1:3],
data = list(mtcars, iris, USArrests)
)
data_getter <- function(data) {
force(data)
function(id_1, id_2) {
where <- data$id_1 == id_1 & data$id_2 == id_2
data[where, ]$data %>%
purrr::flatten_df()
}
}
get_from_tib <- data_getter(tib)
get_from_tib('c', 'C')
#> # A tibble: 50 x 4
#> Murder Assault UrbanPop Rape
#> <dbl> <int> <int> <dbl>
#> 1 13.2 236 58 21.2
#> 2 10 263 48 44.5
#> 3 8.1 294 80 31
#> 4 8.8 190 50 19.5
#> 5 9 276 91 40.6
#> 6 7.9 204 78 38.7
#> 7 3.3 110 77 11.1
#> 8 5.9 238 72 15.8
#> 9 15.4 335 80 31.9
#> 10 17.4 211 60 25.8
#> # … with 40 more rows
object.size(tib)
#> 21752 bytes
object.size(get_from_tib)
#> 8416 bytes
rm(tib)
object.size(get_from_tib)
#> 8416 bytes
由 reprex package (v0.2.1)
于 2019-04-30 创建这与 ?object.size
帮助页面中的
Associated space (e.g., the environment of a function and what the pointer in a EXTPTRSXP points to) is not included in the calculation.
data
变量在闭包中被捕获;它并不是 "in" 从 data_getter
.
pyry::object_size()
函数在考虑封闭环境方面做得更好。
pryr::object_size(tib)
# 21 kB
pryr::object_size(get_from_tib)
# 26.9 kB