【发布时间】:2017-01-13 16:34:18
【问题描述】:
我写了以下两个函数,一个使用连接来测试增加的向量大小,一个使用括号:
c_test <- function(n) {
cv = c()
for(i in 1:n) cv = c(cv, i)
cv
}
b_test <- function(n) {
bv = c()
for (i in 1:n) bv[i] = i
bv
}
library(microbenchmark)
microbenchmark(c_test(1e+4), b_test(1e+4), times = 100)
#Unit: milliseconds
# expr min lq mean median uq max neval
# c_test(10000) 140.27923 145.73282 156.82319 148.16175 151.74713 267.2393 100
# b_test(10000) 49.58033 54.42992 56.24268 54.86033 56.30862 132.8394 100
这是一个很大的时间差异,我不明白为什么使用括号比使用连接好得多。在这两种情况下,分配新内存似乎都需要时间,但这似乎不是真的。我还认为c(v, x) 可能在合并之前将x 转换为与v 相同的类型,但说v[i] = as.vector(x) 并不是一个重要的时间成本。
【问题讨论】:
-
如果需要迭代(通常不需要 -- 向量化),那么最好预先分配和填充
bv = integer(my_len); ... bv[i] = i或者让 R 在迭代期间通过lapply()/ @987654328 管理内存@等 -
你问错问题了。即使我们不考虑矢量化,这两种方法都非常低效。预分配,预分配,预分配。不,真的,预先分配。
-
不,它不是预分配的。
-
我相信区别在于 S3 方法调度的开销,但我在手机上无法检查。尝试使用 c.default。
-
随着大小的增加,对象的增长会变得更加昂贵。
标签: r