这对于评论来说太长了——但不是一个完整的答案。
就修改时的复制而言,命名列表与未命名列表的处理方式不同。
复制(对于大型对象)
这是一个复杂的问题。请参阅http://radfordneal.wordpress.com/2013/07/02/fixing-rs-named-problems-in-pqr/以获得合理的解释,并注意其中一些更改正在 R 的开发版本中实现。另请参阅http://r.789695.n4.nabble.com/Confused-about-NAMED-td4103326.html以进一步了解潜在的复杂性
以下是各种预分配可能性的一些时间安排
# preallocated contents so timing is list related only
.a <- seq_len(1e6); .b <- seq_len((1e6 + 1))
.c <- seq_len((1e6 + 2)); .d <- seq_len((1e6 + 3))
f1 <- function(){
# using `$<-` empty list
x <- list()
x$a <- .a
x$b <- .b
x$c <- .c
x$d <- .d
x
}
f2 <- function(){
# using `[[<-` on empty list
x <- list()
x[['a']] <- .a
x[['b']] <- .b
x[['c']] <- .c
x[['d']] <- .d
x
}
f3 <- function(){
# using `[[<-` on empty list, naming later
x <- list()
x[[1]] <- .a
x[[2]] <- .b
x[[3]] <- .c
x[[4]] <- .d
names(x) <- letters[1:4]
x
}
f4 <- function(){
# just define the list
x <- list(a = .a, b = .b,
c = .c, d = .d)
}
f5 <- function(){
# create a list of length 4, then fill and name
x <- vector(mode = 'list', length = 4)
x[[1]] <- .a
x[[2]] <- .b
x[[3]] <- .c
x[[4]] <- .d
names(x) <- letters[1:4]
x
}
# f6 <- function(){
# # this doesn't work!
# # it creates a list of length 8
# x <- vector(mode = 'list', length = 4)
# x[['a']] <- .a
# x[['b']] <- .b
# x[['c']] <- .c
# x[['d']] <- .d
# x
# }
f7 <-function(){
# pre allocate list, name then fill
x <- vector(mode = 'list', length = 4)
names(x) <- letters[1:4]
x[[1]] <- .a
x[[2]] <- .b
x[[3]] <- .c
x[[4]] <- .d
x
}
f8 <- function(){
# preallocate correct length and then name
# and fill by name
x <- vector(mode = 'list', length = 4)
names(x) <- letters[1:4]
x[['a']] <- .a
x[['b']] <- .b
x[['c']] <- .c
x[['d']] <- .d
x
}
library(microbenchmark)
microbenchmark(f1(),f2(),f3(),f4(),f5(),f7(),f8(),times=100)
microbenchmark(f1(),f2(),f3(),f4(),f5(),f7(),f8(),times=100)
# Unit: microseconds
# expr min lq median uq max neval
# f1() 6.038 11.169 12.980 14.791 34.110 100
# f2() 2528.881 4387.962 4707.014 6472.823 74586.266 100
# f3() 2532.805 4537.376 4714.258 5353.722 74903.206 100
# f4() 2475.756 4531.489 4721.503 6331.860 74460.395 100
# f5() 2508.959 4512.474 4759.535 6673.551 7966.668 100
# f7() 2545.181 4477.761 4709.127 6372.610 7964.856 100
# f8() 2508.053 4467.799 4669.131 6181.993 74236.726 100
#
# All results are identical.
all(identical(f1(),f2()),identical(f1(),f3()),
identical(f1(),f4()),identical(f1(),f5()),
identical(f1(),f7()),identical(f1(),f8()))
# [1] 是的
所有结果都是相同的。
显然在空列表上使用 $<-` 是明显的赢家。这违背了我对什么应该是最快的想法