我是否可以找到HashSet,TreeSet,List等集合上的预期时间和空间复杂性?
是否只是希望从抽象数据类型本身的属性中知道这些?
我知道Performance characteristics for Scala collections,但这只提到了一些非常基本的操作。也许这些集合的其余操作纯粹是从一个小的基础集构建的,但是,似乎我只是希望知道他们已经以这种方式实现了它们?
答案 0 :(得分:8)
其他方法的指南应该是 - 只考虑一个有效的实现应该是什么样的。
集合上的大多数其他批量操作(处理集合中每个元素的操作)都是O(n)
,所以在那里没有提到它们。示例包括filter
,map
,foreach
,indexOf
,reverse
,find
......
返回像combinations
和permutations
这样的迭代器或流的方法通常是O(1)
。
涉及2个集合的方法通常为O(max(n, m))
或O(min(n, m))
。这些是zip
,zipAll
,sameElements
,corresponds
,...
方法union
,diff
和intersect
为O(n + m)
。
排序变体自然是O(nlogn)
。当前实施中groupBy
为O(nlogn)
。 indexOfSlice
使用KMP算法且为O(m + n)
,其中m
和n
是字符串的长度。
+:
,:+
或patch
等方法通常也是O(n)
,除非您正在处理对其进行操作的不可变集合的特定情况。问题更有效 - 例如,在功能List
上添加元素或在Vector
附加元素。
方法toX
通常为O(n)
,因为它们必须迭代所有元素并创建新集合。一个例外是toStream
懒惰地构建集合 - 所以它是O(1)
。此外,只要X
是集合toX
的类型,只需返回this
,即O(1)
。
迭代器实现应该有O(1)
(摊销)next
和hasNext
操作。迭代器创建应该是最坏情况O(logn)
,但在大多数情况下是O(1)
。
答案 1 :(得分:4)
其他方法的性能特征确实难以断言。请考虑以下事项:
foreach
或iterator
实现的,并且通常在层次结构中处于非常高的水平。例如,Vector
的{{1}}已在map
上实施。
为了增加对伤害的侮辱,使用哪种方法实现取决于类继承的线性化。这也适用于任何称为帮助程序的方法。之前发生过这种变化导致无法预料的性能问题。
由于collection.TraversableLike
和foreach
都是iterator
,因此任何改进的效果都取决于其他方法的专业化,例如O(n)
和size
。因此,结果是定义方法的位置 - 并且已记录 - 没有足够的信息来说明其性能特征,并且可能不仅取决于继承集合如何实现其他方法,而且甚至可以通过调用站点传递的从CanBuildFrom获取的对象Builder的性能特征。
充其量,任何此类文档都将根据其他方法进行描述。这并不意味着它不值得,但它并不容易实现 - 开源项目的艰巨任务取决于志愿者,他们通常按照自己喜欢的方式工作,而不是需要。