【问题标题】:What is the internal implementation of lists?列表的内部实现是什么?
【发布时间】:2013-08-25 10:20:16
【问题描述】:

我很好奇list 类型的对象是如何实现的。是吗

  1. 一个动态向量,当它已满时会自动增加其大小。
  2. 一个链表,其中附加一个项目是O(1),但访问一个项目是O(n)
  3. 具有O(log(n)) 项目访问权限的树结构。
  4. 具有O(1) 项目访问权限的哈希表。

我很好奇,因为列表可以有键值对,使它们看起来像哈希表,但元素是有序的,看起来像一个向量。

编辑:因为length(list(runif(1e4)))是1,所以当追加元素到列表时,看起来每次都复制整个列表,速度很慢:

但是访问速度比向量慢很多:

z1 <- runif(1e4)
system.time({
  for(i in 1:10000) z1[[1 + i]] <- 1
})

输出:

user  system elapsed 
0.060   0.000   0.062 

但是:

z1 <- list(runif(1e4))
system.time({
  for(i in 1:10000) z1[[1 + i]] <- 1
})

输出:

user  system elapsed 
1.31    0.00    1.31 

初始化一个包含 10000 个元素的列表:

z1 <- as.list(runif(1e4))
system.time({
  for(i in 1:10000) z1[[1 + i]] <- 1
})

输出:

user  system elapsed 
0.060   0.000   0.065 

对于键和值访问:

z1 <- list()
for(i in 1:10000){key <- as.character(i); z1[[key]] <- i} 
system.time({
  for(i in 1:10000) x <- z1[["1"]]
})
system.time({
  for(i in 1:10000) x <- z1[["10000"]]
})

输出是:

user  system elapsed 
0.01    0.00    0.01 
user  system elapsed 
1.78    0.00    1.78 

这不是O(1) 访问,所以它不是哈希表。我的结论是它不是一个动态数组,因为附加项目每次都会导致内存访问;它不是哈希表,因为按键访问不是O(1)

【问题讨论】:

  • 如果您将分析放在答案中(应该是恕我直言),我会投票给您两次。

标签: r list


【解决方案1】:

列表本质上只是 R 对象的数组 (SEXP)。调整大小会导致整个数据的副本,并且名称查找是线性的。

或者,您可以使用在内部使用哈希表的环境。

【讨论】:

  • 那么如果listSEXPs 的数组,为什么查找是线性的而不是恒定的?还是 name 查找线性和 indexed 查找常量?
  • 我确实写了名称查找。
  • 我找不到在 R 与 lapply 中增加列表时性能下降的案例?示例代码 system.time({ l = list(); for(i in 1:50000) l[[i]] = letters}) 对于大多数实际问题来说,这不是问题吗?除了字母,它还可以是一些随机数,由 rnorm 生成。
猜你喜欢
  • 2020-05-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-28
  • 1970-01-01
  • 2010-12-17
  • 1970-01-01
相关资源
最近更新 更多