我应该使用List [A]还是Seq [A]还是别的什么?

时间:2010-09-03 08:13:02

标签: design-patterns scala

我正在写一个包含一些功能性方法的类。首先,我使用List作为参数和返回类型编写它们。然后我想“嘿,你也可以使用更通用的类型!”所以我用Seq替换了Lists,希望有一天我可以通过提供除列表以外的东西来让我的东西更快。

那么我应该为哪些通用的堆栈式数据结构编写我的方法和算法?我能坚持一般的模式吗?所有这一切都是因为这些方法可能需要在将来进行优化,以防它们形成瓶颈。

更新

我会尝试更精确一点: 如果您知道正在使用哪些操作,例如反转,.tail,直接元素访问或理解。我可以选择一种强制效率的类型吗?

更新2

我非常清楚各种任务的具体数据结构的性能。我不知道的是哪个数据结构可能显示为某种超类型的子类。

例如,我应该使用TraversableOnce或IndexedSeq而不是List或Array吗?它会给我买什么吗?

附加问题

什么是您的默认类似列表的数据结构签名?你写的是

吗?
def a(b: List[A]): List[A] 

def a(b: TraversableOnce[A]): TraversableOnce[A]

你能解释一下原因吗?

3 个答案:

答案 0 :(得分:30)

ListLinearSeq的默认实现,后者又是Seq的默认实现,后者又是Iterable的默认实现,是Traversable的默认实现。

参见图表here并根据您的要求选择最常用的类型。


alt text


This文件也可能会有所帮助。

答案 1 :(得分:12)

我认为,一般来说,您应该使用Seq作为参数,并设计方法以便有效地使用List。通过这种方式,您的方法可以在大多数Seq实现中正常运行,您无需在使用方法之前转换seq。

修改

你的问题里面有很多问题。

  1. 那么我应该为哪些通用的堆栈式数据结构编写我的方法和算法?
    • 我认为这里的答案是List。这是一个堆栈,它非常快
  2. 我可以选择一种能够提高效率吗?
  3. 例如,我应该使用TraversableOnce或IndexedSeq而不是List或Array吗?它会给我买什么东西吗?
    • 某些抽象具有定义的性能特征,而其他抽象则没有定义。例如IndexedSeq scaladoc说“索引序列支持恒定时间或接近恒定时间的元素访问和长度计算”。如果你有一个IndexedSeq参数并且有人通过了一个没有“接近恒定时间元素访问权限”的IndexedSeq实现,那么有人违反合同并且这不是你的问题。
  4. 您的默认类似列表的数据结构签名是什么?
    • SEQ

答案 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?,了解您将遇到的问题以及一些解决方案。