有趣的是,答案竟然是两个O(1) 和O(n)。时机与其说取决于列表的长度,不如说是在获得你想要的命名元素之前的列表长度。
让我们定义一些不同长度的列表:
library(microbenchmark)
makelist <- function(n){
L <- as.list(runif(n))
names(L) <- paste0("Element", 1:n)
return(L)
}
L100 <- makelist(100)
L1000 <- makelist(1000)
LMillion <- makelist(10^6)
L10Million <- makelist(10^7)
如果我们尝试从其中的每一个中提取名为 Element100our 的元素 - 第 100 个元素 - 所需的时间长度基本相同:
microbenchmark(
L10Million[["Element100"]],
LMillion[["Element100"]],
L1000[["Element100"]],
L100[["Element100"]]
)
Unit: nanoseconds
expr min lq mean median uq max neval cld
L10Million[["Element100"]] 791 791 996.59 792 1186 2766 100 a
LMillion[["Element100"]] 791 791 1000.56 989 1186 1976 100 a
L1000[["Element100"]] 791 791 1474.64 792 1186 28050 100 a
L100[["Element100"]] 791 791 1352.21 792 1186 17779 100 a
但是如果我们尝试获取最后一个元素,需要的时间是O(n)
microbenchmark(
L10Million[["Element10000000"]],
LMillion[["Element1000000"]],
L1000[["Element1000"]],
L100[["Element100"]]
)
Unit: nanoseconds
expr min lq mean median uq max neval cld
L10Million[["Element10000000"]] 154965791 165074635 172399030.13 169602043 175170244 235525230 100 c
LMillion[["Element1000000"]] 15362773 16540057 17379942.70 16967712 17734922 22361689 100 b
L1000[["Element1000"]] 9482 10668 17770.94 16594 20544 67557 100 a
L100[["Element100"]] 791 1186 3995.15 3556 6322 24100 100 a
library(ggplot2)
library(dplyr)
res <- data.frame(x = c(100, 1000, 10^6, 10^7),
y = c(3556, 16594, 16967715, 169602041))
ggplot(res, aes(x = x, y = y ))+
geom_smooth(method = "lm") +
geom_point(, size = 3) +
scale_x_log10() +
scale_y_log10()