我正在写一个包含一些功能性方法的类。首先,我使用List作为参数和返回类型编写它们。然后我想“嘿,你也可以使用更通用的类型!”所以我用Seq替换了Lists,希望有一天我可以通过提供除列表以外的东西来让我的东西更快。
那么我应该为哪些通用的堆栈式数据结构编写我的方法和算法?我能坚持一般的模式吗?所有这一切都是因为这些方法可能需要在将来进行优化,以防它们形成瓶颈。
我会尝试更精确一点: 如果您知道正在使用哪些操作,例如反转,.tail,直接元素访问或理解。我可以选择一种强制效率的类型吗?
我非常清楚各种任务的具体数据结构的性能。我不知道的是哪个数据结构可能显示为某种超类型的子类。
例如,我应该使用TraversableOnce或IndexedSeq而不是List或Array吗?它会给我买什么吗?
什么是您的默认类似列表的数据结构签名?你写的是
吗?def a(b: List[A]): List[A]
或
def a(b: TraversableOnce[A]): TraversableOnce[A]
你能解释一下原因吗?
答案 0 :(得分:30)
List
是LinearSeq
的默认实现,后者又是Seq
的默认实现,后者又是Iterable
的默认实现,是Traversable
的默认实现。
参见图表here并根据您的要求选择最常用的类型。
This文件也可能会有所帮助。
答案 1 :(得分:12)
我认为,一般来说,您应该使用Seq
作为参数,并设计方法以便有效地使用List
。通过这种方式,您的方法可以在大多数Seq
实现中正常运行,您无需在使用方法之前转换seq。
修改强>
你的问题里面有很多问题。
List
。这是一个堆栈,它非常快IndexedSeq
scaladoc说“索引序列支持恒定时间或接近恒定时间的元素访问和长度计算”。如果你有一个IndexedSeq
参数并且有人通过了一个没有“接近恒定时间元素访问权限”的IndexedSeq
实现,那么有人违反合同并且这不是你的问题。 答案 2 :(得分:5)
有关集合库的背景信息,请查看Scala 2.8 Collections API文章。
如果您有特定的操作,请特别注意Performance Characteristics section。
关于是否使用特定类型的更一般特征的设计选择,我会说这取决于你在实现中做了什么。例如,如果一个方法接受一个List,它可以指望快速前置,并可以在其实现中使用它。因此,接受更一般的特征可能会产生不必要的性能结果。此外,你将不得不担心你得到什么类型。
scala> def a[A](t:TraversableOnce[A]): TraversableOnce[A] = t
a: [A](t: TraversableOnce[A])TraversableOnce[A]
scala> a(List(1,2))
res0: TraversableOnce[Int] = List(1, 2)
scala> res0.tail
<console>:8: error: value tail is not a member of TraversableOnce[Int]
res0.tail
如果你想写一些一般的东西,你可能想要保留类型。请参阅Can I "pimp my library" with an analogue of TraversableLike.map that has nicely variant types?,了解您将遇到的问题以及一些解决方案。