Scala集合转换性能:单循环与多循环

时间:2013-10-12 20:33:27

标签: performance scala collections iteration scala-collections

当有集合并且您必须对其所有元素执行两个或更多操作时,更快的是什么?:

val f1: String => String  = _.reverse
val f2: String => String  = _.toUpperCase
val elements: Seq[String] = List("a", "b", "c")
  1. 多次迭代并在一个循环上执行一个操作

    val result = elements.map(f1).map(f2)

    这种方法的优势在于,可以重复应用第一个函数后的结果。

  2. 迭代一次并对每个元素一起执行所有操作

    val result = elements.map(element => f2(f1(element)))

    val result = elements.map(element => f1.compose(f2)

  3. 这两种方法的性能有何不同?如果是,哪个更快?

2 个答案:

答案 0 :(得分:4)

这就是事情,集合的转换或多或少是运行时O(N),*所有应用函数的运行时成本。所以我怀疑你上面提到的第二组选择会在运行时产生最微小的差别。您列出的第一个选项是另一个故事。可以避免创建新的集合,因为这可能导致开销。这就是“视图”集合的用武之地(参见我发现的这个好例子)

In Scala, what does "view" do?

如果你有几个映射操作,你可以这样做:

val result = elements.view.map(f1).map(f2).force

(强制结束,导致所有功能评估) 上面的第二组示例可能会快一点,但如果您在映射中使用了大量这些或复杂的匿名函数,则“view”选项可以使您的代码更具可读性。

答案 1 :(得分:1)

组合函数以产生单次传递转换可能会获得一些性能,但很快就会变得难以理解。考虑使用视图作为alernative。虽然这将创建中间集合:

val result = elements.map(f1).map(f2)

这将执行延迟评估,并将以与您相同的方式执行功能组合:

val result = elements.view.map(f1).map(f2)

请注意,结果类型为SeqView,因此您可能希望稍后使用toList将其转换为列表。