【问题标题】:Should I use List[A] or Seq[A] or something else?我应该使用 List[A] 还是 Seq[A] 还是其他什么?
【发布时间】:2011-04-07 17:38:45
【问题描述】:

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

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

更新

我会尽量准确一点: 假设您知道您正在使用哪些操作,例如反转、.tail、直接元素访问或推导式。我可以选择一种类型来强制提高这些操作的效率吗?

更新 2

我非常了解具体数据结构在各种任务中的性能。我不知道哪种数据结构可能会显示为某些超类型的子类。

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

附加问题

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

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

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

你能解释一下原因吗?

【问题讨论】:

  • 也许我面临的问题是我知道可能有 5 个集合实现和 50 个超类型/特征。我知道我必须选择哪个实现,但不知道哪个特征。

标签: design-patterns scala


【解决方案1】:

ListLinearSeq的默认实现,又是Seq的默认实现,又是Iterable的默认实现,又是Traversable的默认实现.

查看图表here 并根据您的要求选择最通用的类​​型。



This 文档也可能有帮助。

【讨论】:

    【解决方案2】:

    我认为,一般来说,您应该使用Seq 作为参数,并设计您的方法以有效地使用List。这样,您的方法将适用于大多数 Seq 实现,并且您不必在使用您的方法之前转换您的序列。

    编辑

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

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

    【讨论】:

    • 这基本上是我在我的项目中所做的。这是我所希望的那种答案,但现在我在想,也许不存在一个好的全面答案。
    • 一个问题是你的问题里面有很多问题,我已经更新了我的答案,试图更具体地解决每个问题
    【解决方案3】:

    有关收藏库的背景信息,请查看Scala 2.8 Collections API 文章。

    如果您有特定的操作,请特别查看Performance Characteristics section

    关于是否使用更通用特征的特定类型的设计选择,我想说这取决于您在实现中所做的事情。例如,如果一个方法接受一个列表,它可以依靠快速前置并可以在其实现中使用它。因此,接受更一般的特征可能会产生不希望的性能结果。此外,您还必须担心返回的类型。

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

    【讨论】:

      猜你喜欢
      • 2017-05-22
      • 2011-08-21
      • 2011-12-18
      • 2013-08-24
      • 2017-01-06
      • 1970-01-01
      • 2012-02-11
      • 2010-10-25
      • 2021-05-08
      相关资源
      最近更新 更多