前面的解释已经明确,不同的集合类型具有不同的性能特征。这通常是选择一种集合类型而不是另一种集合类型的主要原因。你可以在下表中看到集合上一些常见操作的性能特征总结。
序列类型的性能特征
head | tail | apply | update | prepend | append | insert | |
---|---|---|---|---|---|---|---|
immutable | |||||||
List |
C | C | L | L | C | L | - |
LazyList |
C | C | L | L | C | L | - |
ArraySeq |
C | L | C | L | L | L | - |
Vector |
eC | eC | eC | eC | eC | eC | - |
Queue |
aC | aC | L | L | L | C | - |
Range |
C | C | C | - | - | - | - |
String |
C | L | C | L | L | L | - |
mutable | |||||||
ArrayBuffer |
C | L | C | C | L | aC | L |
ListBuffer |
C | L | L | L | C | C | L |
StringBuilder |
C | L | C | C | L | aC | L |
Queue |
C | L | L | L | C | C | L |
ArraySeq |
C | L | C | C | - | - | - |
Stack |
C | L | L | L | C | L | L |
Array |
C | L | C | C | - | - | - |
ArrayDeque |
C | L | C | C | aC | aC | L |
集合和映射类型的性能特征
lookup | add | remove | min | |
---|---|---|---|---|
immutable | ||||
HashSet /HashMap |
eC | eC | eC | L |
TreeSet /TreeMap |
Log | Log | Log | Log |
BitSet |
C | L | L | eC1 |
VectorMap |
eC | eC | aC | L |
ListMap |
L | L | L | L |
mutable | ||||
HashSet /HashMap |
eC | eC | eC | L |
WeakHashMap |
eC | eC | eC | L |
BitSet |
C | aC | C | eC1 |
TreeSet |
Log | Log | Log | Log |
脚注:1 假设位紧密打包。
这两个表中的条目解释如下
C | 操作需要(快速)常量时间。 |
eC | 操作需要有效常量时间,但这可能取决于某些假设,例如向量的最大长度或哈希键的分布。 |
aC | 操作需要摊销常量时间。操作的某些调用可能需要更长时间,但如果对许多操作执行,则平均每个操作只需要常量时间。 |
Log | 操作需要与集合大小的对数成正比的时间。 |
L | 此操作是线性的,也就是说它需要与集合大小成正比的时间。 |
- | 不支持此操作。 |
第一个表使用以下操作处理序列类型(不可变和可变)
head | 选择序列的第一个元素。 |
tail | 生成一个包含除第一个元素之外的所有元素的新序列。 |
apply | 索引。 |
update | 不可变序列的功能更新(使用 updated ),可变序列的副作用更新(使用 update )。 |
prepend | 向序列的开头添加一个元素。对于不可变序列,这会生成一个新序列。对于可变序列,它会修改现有序列。 |
append | 向序列的末尾添加一个元素。对于不可变序列,这会生成一个新序列。对于可变序列,它会修改现有序列。 |
insert | 在序列中的任意位置插入一个元素。这仅直接支持可变序列。 |
第二个表使用以下操作处理可变和不可变集合和映射
lookup | 测试元素是否包含在集合中,或选择与键关联的值。 |
add | 向集合添加一个新元素,或向映射添加一个键值对。 |
remove | 从集合中删除一个元素,或从映射中删除一个键。 |
min | 集合中最小的元素,或映射中最小的键。 |