我一直在做一些需要对列表进行大量子集操作的项目,通过对代码进行剖析,我发现 object[["nameHere"]] 这种方式通常比 object$nameHere 更快。
以一个创建了具有命名组件的列表为例:
a.long.list <- as.list(rep(1:1000))
names(a.long.list) <- paste0("something",1:1000)
为什么会这样:
system.time (
for (i in 1:10000) {
a.long.list[["something997"]]
}
)
user system elapsed
0.15 0.00 0.16
比这个速度更快:
system.time (
for (i in 1:10000) {
a.long.list$something997
}
)
user system elapsed
0.23 0.00 0.23
我想知道这种行为是否普遍存在,以及我是否应该尽可能避免使用 $ subset 或者最有效的选择取决于其他因素?
$
符号的部分匹配有关。假设你有一个列表my_list <- list("a" = 1, "ace" = 2)
。如果你尝试my_list$ac
,它会得到ace
,但如果你尝试my_list[["ac"]]
,它会找不到任何东西。 - Frank[[
中添加exact = FALSE
不会降低性能。 - flodel$
和[[
是由两个完全不同的C函数实现的(均在src/main/subset.c
中)。对于$
,相关函数是do_subset3
,该函数又调用R_subset3_dflt
。而[[
则使用另一个函数do_subset2
,该函数又调用do_subset2_dflt
。 - Josh O'Briendo_subset2
之前的注释简单地提到:“[[子集运算符。需要快速执行。” - Josh O'Brien