Thú vị, câu trả lời hóa ra là cả haiO(1)
và O(n)
. Thời gian phụ thuộc không quá nhiều vào độ dài của danh sách, vì độ dài của danh sách trước phần tử được đặt tên bạn muốn thu được.
Hãy xác định một số danh sách có độ dài khác nhau:
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)
Nếu chúng ta cố gắng trích xuất các yếu tố được đặt tên Element100
của chúng tôi của mỗi - yếu tố thứ 100 - phải mất cơ bản cùng độ dài của thời gian:
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
Nhưng nếu chúng tôi cố gắng để có được những yếu tố cuối cùng, thời gian cần thiết là 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()
Nguồn
2016-12-28 20:31:04
Điều này cho thấy không phải là 'O (1)': https://www.r-bloggers.com/hash-table-performance-in-r-part-i/ Ngoài ra, hãy xem câu hỏi này: http://stackoverflow.com/q/3470447/4996248 (Liên kết đầu tiên cho thấy rằng nó là 'O (n)'. Họ đang định thời gian tìm kiếm * tất cả * khóa, mà là bậc hai mặc dù họ nhầm lẫn nói nó là theo cấp số nhân). –
Để tìm kiếm giá trị đơn lẻ (ví dụ: '" any_random_name "'), phần có liên quan của ['do_subset2_dflt'] (https://github.com/wch/r-source/blob/d8f952565bb9c48bd524c368f3e4ac0d3de096b0/src/main/subset.C# L1018-L1030) phải là cuộc gọi đến ['get1index'] (https://github.com/wch/r-source/blob/af7f52f70101960861e5d995d3a4bec010bc89e6/src/main/subscript.c#L224-L233), có vẻ như tuyến tính. – nrussell
Một [điểm chuẩn nhanh] (https://gist.github.com/nathan-russell/d09e220899115d85b10c0959188a287b) dường như xác nhận điều này. – nrussell