标准容器的比较
这是对OCaml标准库所提供的不同容器的一个粗略的比较。以下的n
代表容器中元素的数量。
值得注意的是,大O所代表的是当前实现下的效率,并不为官方文档保证。希望以后这些实现不会 变得更糟糕吧。总之,文档才是理解这些模块最好的来源。当然,你也可以尝试阅读源代码。
Lists: 不可变的单链表
添加一个元素会创建一个新的链表l,从x指向链表tl。tl不会被改变,因此不会被拷贝。
- 添加一个元素: O(1), cons 操作符
::
- 长度: O(n),
List.length
- 索引第i个元素: O(i)
- 寻找一个元素: O(n)
这个结构比较适合IO和模式匹配。
但不太适合索引。
数组和字符串:可变数组
数组和字符串很相似。只不过字符串是用来紧凑地存贮字符,和一些方便的语法而已。
- 添加一个元素: O(n)
- 长度: O(1),
Array.length
- 索引第i个元素: O(1)
- 寻找一个元素: O(n)
比较适合一些已知大小的元素,下标索引,和在位编辑。数组和字符串的长度都是固定的。如果你想改变
字符串的长度,Buffer
模块比较合适。
Set 和 Map:不可变的树
如链表,他们都是不可变的,但是他们有可能共享一些子树。他们比较适合用于保存一些旧版本的数据。
- 添加一个元素: O(log n)
- 返回元素的数量: O(n)
- 寻找一个元素: O(log n)
集合和映射对于编译和元编程(meta-programming)都很有用,但是在某些情况,哈希表会更加合适。
Hashtbl: 自动增长的哈希表
Ocaml的哈希表是可变的,可以把键值存储在同一个数据结构。
- 添加一个元素:如果表的初始大小比元素数量要大,则是O(1),如果往很小的表插入n个元素,则平均是O(log n)
- 返回元素的数量: O(1)
- 寻找一个元素: O(1)
Buffer: 可变长字符串
Buffer提供了一个有效的方式在一个数据结构中累计字节。他们是可变的,
- 添加一个元素:如果buffer足够大则是O(1),如果buffer远远小于n,那么则平均是O(log n)。
- 添加一个 k 字符长的字符串: O(k * 添加一个元素)
- 长度: O(1)
- 索引第i个元素: O(1)
Queue
OCaml的队列是可变的FIFO,。
- 添加一个元素:O(1)
- 获取一个元素: O(1)
- 长度: O(1)
Stack
Ocaml的栈是可变的LIFO。他们除了可变以外和链表没有区别。
- 添加一个元素:O(1)
- 获取一个元素: O(1)
- 长度: O(1)